From 34750870ec6c5b929685574b629836e6f767529b Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 9 Nov 2022 15:31:56 +0100 Subject: [PATCH 01/62] typos Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 4f2e92e930..728bc4f3e8 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -8,7 +8,7 @@ SPDX-License-Identifier: MPL-2.0 ## Power-flow calculation -Power flow calculation is done using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) ### Power-flow calculation algorithms @@ -25,7 +25,7 @@ are acceptable. Both methods have equal computation time for a single powerflow * `CalculationMethod.linear`: It will be more accurate when most of the load/generation types are of constant impedance. * `CalculationMethod.linear_current`: It will be more accurate when most of the load/generation types are constant power - or constant current. Batch calculations here will be faster because matrix prefacorization is possible. + or constant current. Batch calculations here will be faster because matrix prefactorization is possible. ## State estimation calculation From 13c87584a5b47bca7f57041c383b636f5d76139e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 11 Nov 2022 11:38:40 +0100 Subject: [PATCH 02/62] calculations skeleton Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 66 +++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 728bc4f3e8..3d7a7aa312 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -6,38 +6,68 @@ SPDX-License-Identifier: MPL-2.0 # Calculations -## Power-flow calculation +## Calculation types +With power-grid-model it is possible to perform two different types of calculation: +- [Power flow](###Power flow algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) +- [State estimation](###State estimation algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) -Power flow calculation is done using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) +### Calculation types explained +TODO: +- What is the difference between power flow and state estimation +- When should you use which? Maybe small example (physical, not code) + +### Power flow algorithms +Two types of power flow algorithms are implemented in power-grid-model; iterative algorithms (Newton-Raphson / Iterative current) and linear algorithms (Linear / Linear current). +Iterative methods are more accurate and should thus be selected when an accurate solution is required. Linear approximation methods are many times faster than the iterative methods, in tradeoff to accuracy. +They can be used where approximate solutions are acceptable. The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. +TODO: fill in the table below. Maybe add some other column if that would make the decision to choose an algorithm easier. -### Power-flow calculation algorithms +| Algorithm | Speed | Accuracy | Radial grid | Meshed grid | Algorithm call | +|--------------------------------------------|----------|----------|-------------|-------------|---------------------------------------| +| [Newton-Raphson](####Newton-Raphson) | | ✔ | | | `CalculationMethod.newton_raphson` | +| [Iterative current](####Iterative current) | | ✔ | | | `CalculationMethod.iterative_current` | +| [Linear](####Linear) | ✔ | | | | `CalculationMethod.linear` | +| [Linear current](####Linear current) | ✔ | | | | `CalculationMethod.linear_current` | -These should be selected when accurate solution is required within specified `error_tolerance`. +TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. -* `CalculationMethod.newton_raphson`: Traditional Newton-Raphson method. -* `CalculationMethod.iterative_current`: Newton-Raphson would be more robust in achieving convergence and require less - iterations. However, Iterative current can be faster most times because it - uses [](./performance-guide.md#matrix-prefactorization). +#### Newton-Raphson +Traditional Newton-Raphson method. -Linear approximation methods are many times faster than the iterative methods. Can be used where approximate solutions -are acceptable. Both methods have equal computation time for a single powerflow calculation. +#### Iterative Current +Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . -* `CalculationMethod.linear`: It will be more accurate when most of the load/generation types are of constant impedance. -* `CalculationMethod.linear_current`: It will be more accurate when most of the load/generation types are constant power - or constant current. Batch calculations here will be faster because matrix prefactorization is possible. +#### Linear +It will be more accurate when most of the load/generation types are of constant impedance. -## State estimation calculation +#### Linear current +It will be more accurate when most of the load/generation types are constant power or constant current. Batch calculations here will be faster because matrix prefactorization is possible. -State Estimation is done using the {py:class}`calculate_state_estimation `. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) +## Power-flow calculation + +Power flow calculation is done using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) -### State Estimation algorithms -* `CalculationMethod.iterative_linear`: It is an iterative method which converges to a true - solution. [](./performance-guide.md#matrix-prefactorization) is possible. +### State estimation algorithms +At the moment one state estimation algorithm is implemented: [iterative linear](####Iterative linear). + +#### Iterative linear + +TODO: extend the explanation of the algorithm. + +Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method which converges to a true + solution. [Matrix-prefactorization](./performance-guide.md#matrix-prefactorization) is possible. ## Batch Calculations +TODO, add explanation on batch calculations: +- when to use batch calculations +- what are the batch options +- how to use it +- something else? + + ```{warning} [Issue 79](https://github.com/alliander-opensource/power-grid-model/issues/79) ``` From 844ca39e0c3367261824f38609ba5daf25b84623 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 14 Nov 2022 17:20:04 +0100 Subject: [PATCH 03/62] data-validator.md so far Signed-off-by: Peter Salemink --- docs/user_manual/data-validator.md | 41 +++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/user_manual/data-validator.md b/docs/user_manual/data-validator.md index ad6951cb27..adbe39436f 100644 --- a/docs/user_manual/data-validator.md +++ b/docs/user_manual/data-validator.md @@ -6,11 +6,14 @@ SPDX-License-Identifier: MPL-2.0 # Data Validator +TODO: remove this issue once the page is updated ```{warning} [Issue 79](https://github.com/alliander-opensource/power-grid-model/issues/79) ``` - -For performance reasons, the input/update data is not automatically validated. The main validation functions and classes can be included from `power_grid_model.validation`. +The power-grid-model repository provides an input/update data validator. For performance reasons, the input/update data is not automatically validated. +However, it would be advisable to validate your data before constructing a PowerGridModel instance. +An alternative approach would be to validate only when an exception is raised, but be aware that not all data errors will raise exceptions, most of them wil just yield invalid results without warning. +The main validation functions and classes can be included from `power_grid_model.validation`. Two helper type definitions are used throughout the validation functions, `InputData` and `UpdateData`. They are not special types or classes, but merely type hinting aliases: @@ -21,10 +24,40 @@ UpdateData = Dict[str, Union[np.ndarray, Dict[str, np.ndarray]]] ``` ```{seealso} -Check [](examples/Validation%20Examples.ipynb) for an example of function applications. +Check the [example](examples/Validation%20Examples.ipynb) for an example of function applications. ``` ## Validation Errors +Each validation error is an object which can be converted to a compact human-readable message using `str(error)`. +It contains three member variables `component`, `field` and `ids`, which can be used to gather more specific information about the validation error, +e.g. which object IDs are involved. + +``` +class ValidationError: + + # Component(s): e.g. "node" or ["node", "line"] + component: Union[str, List[str]] + + # Field(s): e.g. "id" or ["line_from", "line_to"] or [("node", "id"), ("line", "id")] + field: Union[str, List[str], List[Tuple[str, str]]] + + # IDs: e.g. [1, 2, 3] or [("node", 1), ("line", 1)] + ids: Union[List[int], List[Tuple[str, int]]] = [] +``` + +## Validation functions +Manual validation +- `validate_input_data(input_data, calculation_type, symmetric) -> List[ValidationError]` assumes that you won't be using update data in your calculation. +- `validate_batch_data(input_data, update_data, calculation_type, symmetric) -> Dict[int, List[ValidationError]]` validates input_data in combination with batch/update data. + +Assertions + +Instead of manual validation it is possible to use the assertion functions below to assert valid data. In the case of invalid data a `ValidationException` will be raised, +which is an exception storing the name of the validated data, a list/dict of errors and a convenient conversion to string +to display a summary of all the errors when printing the exception. +- `assert_valid_input_data(input_data, calculation_type, symmetric)` raises `ValidationException` +- `assert_valid_batch_data(input_data, calculation_type, update_data, symmetric)` raises `ValidationException` -## Validation functions \ No newline at end of file +Utilities +- `errors_to_string(errors, name, details)` converts a set of errors to a human-readable (multi-line) string representation \ No newline at end of file From fdecd15611fd833d898781a333f0b5fd7a259611 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 15 Nov 2022 11:26:41 +0100 Subject: [PATCH 04/62] validator docs Signed-off-by: Peter Salemink --- docs/user_manual/data-validator.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/user_manual/data-validator.md b/docs/user_manual/data-validator.md index adbe39436f..1360f2df90 100644 --- a/docs/user_manual/data-validator.md +++ b/docs/user_manual/data-validator.md @@ -6,10 +6,6 @@ SPDX-License-Identifier: MPL-2.0 # Data Validator -TODO: remove this issue once the page is updated -```{warning} -[Issue 79](https://github.com/alliander-opensource/power-grid-model/issues/79) -``` The power-grid-model repository provides an input/update data validator. For performance reasons, the input/update data is not automatically validated. However, it would be advisable to validate your data before constructing a PowerGridModel instance. An alternative approach would be to validate only when an exception is raised, but be aware that not all data errors will raise exceptions, most of them wil just yield invalid results without warning. @@ -47,11 +43,15 @@ class ValidationError: ``` ## Validation functions -Manual validation -- `validate_input_data(input_data, calculation_type, symmetric) -> List[ValidationError]` assumes that you won't be using update data in your calculation. +#### Manual validation +The validation functions below can be used to validate input/batch data manually. The functions require `input_data: InputData `, which is power-grid-model input data, +and `symmetric: bool`, stating if the data will be used for symmetric or asymmetric calculations. `calculation_type: CalculationType` is optional and can be supplied to +allow missing values for unused fields; see the [API reference](../api_reference/python-api-reference.md#enum) for more information. To validate update/batch data `update_data: UpdateData`, +power-grid-model update data, should also be supplied. +- `validate_input_data(input_data, calculation_type, symmetric) -> List[ValidationError]` validates input_data. - `validate_batch_data(input_data, update_data, calculation_type, symmetric) -> Dict[int, List[ValidationError]]` validates input_data in combination with batch/update data. -Assertions +#### Assertions Instead of manual validation it is possible to use the assertion functions below to assert valid data. In the case of invalid data a `ValidationException` will be raised, which is an exception storing the name of the validated data, a list/dict of errors and a convenient conversion to string @@ -59,5 +59,9 @@ to display a summary of all the errors when printing the exception. - `assert_valid_input_data(input_data, calculation_type, symmetric)` raises `ValidationException` - `assert_valid_batch_data(input_data, calculation_type, update_data, symmetric)` raises `ValidationException` -Utilities -- `errors_to_string(errors, name, details)` converts a set of errors to a human-readable (multi-line) string representation \ No newline at end of file +#### Utilities +- `errors_to_string(errors, name, details)` converts a set of errors to a human-readable (multi-line) string representation + +```{seealso} +For more information on the validation functions please see the [API reference](../api_reference/python-api-reference.md#validation). +``` \ No newline at end of file From ddd0a9bb3e98977ce8a015e5efa27990e0386c7b Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 18 Nov 2022 16:12:50 +0100 Subject: [PATCH 05/62] adress comments Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 3d7a7aa312..c4bbf90d49 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -23,14 +23,15 @@ They can be used where approximate solutions are acceptable. The table below can TODO: fill in the table below. Maybe add some other column if that would make the decision to choose an algorithm easier. -| Algorithm | Speed | Accuracy | Radial grid | Meshed grid | Algorithm call | -|--------------------------------------------|----------|----------|-------------|-------------|---------------------------------------| -| [Newton-Raphson](####Newton-Raphson) | | ✔ | | | `CalculationMethod.newton_raphson` | -| [Iterative current](####Iterative current) | | ✔ | | | `CalculationMethod.iterative_current` | -| [Linear](####Linear) | ✔ | | | | `CalculationMethod.linear` | -| [Linear current](####Linear current) | ✔ | | | | `CalculationMethod.linear_current` | +| Algorithm | Speed | Accuracy | Algorithm call | +|--------------------------------------------|----------|----------|---------------------------------------| +| [Newton-Raphson](####Newton-Raphson) | | ✔ | `CalculationMethod.newton_raphson` | +| [Iterative current](####Iterative current) | | ✔ | `CalculationMethod.iterative_current` | +| [Linear](####Linear) | ✔ | | `CalculationMethod.linear` | +| [Linear current](####Linear current) | ✔ | | `CalculationMethod.linear_current` | TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. +Also include the mathematics/algorithms. #### Newton-Raphson Traditional Newton-Raphson method. @@ -65,6 +66,7 @@ TODO, add explanation on batch calculations: - when to use batch calculations - what are the batch options - how to use it +- explain independent batches and caching topology - something else? From f9fe72dd3afd387210be04a989f993410eb3cc02 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 18 Nov 2022 16:17:45 +0100 Subject: [PATCH 06/62] remove 1 todo Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index c4bbf90d49..49cf816266 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -21,8 +21,6 @@ Two types of power flow algorithms are implemented in power-grid-model; iterativ Iterative methods are more accurate and should thus be selected when an accurate solution is required. Linear approximation methods are many times faster than the iterative methods, in tradeoff to accuracy. They can be used where approximate solutions are acceptable. The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. -TODO: fill in the table below. Maybe add some other column if that would make the decision to choose an algorithm easier. - | Algorithm | Speed | Accuracy | Algorithm call | |--------------------------------------------|----------|----------|---------------------------------------| | [Newton-Raphson](####Newton-Raphson) | | ✔ | `CalculationMethod.newton_raphson` | From 1170a5d70a59bd096dd692e9847ec2c10403bf2e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 18 Nov 2022 16:36:59 +0100 Subject: [PATCH 07/62] pf Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 49cf816266..4a2557f483 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -16,6 +16,20 @@ TODO: - What is the difference between power flow and state estimation - When should you use which? Maybe small example (physical, not code) +#### Power flow +Power flow is a "what-if" based grid calculation that will calculate the node voltages and the power flow through the branches, based on assumed load/generation profiles. +Some typical use-cases are network planning and contingency analysis. + +Input: +- Network data: topology + component attributes +- Assumed load/generation profile + +Output: +- Node voltage magnitude and angle +- Power flow through branches + +#### State estimation + ### Power flow algorithms Two types of power flow algorithms are implemented in power-grid-model; iterative algorithms (Newton-Raphson / Iterative current) and linear algorithms (Linear / Linear current). Iterative methods are more accurate and should thus be selected when an accurate solution is required. Linear approximation methods are many times faster than the iterative methods, in tradeoff to accuracy. From 9af1956f35c93fb9e6721b8b5929339618d9a5b8 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 15:50:42 +0100 Subject: [PATCH 08/62] SE temp save Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 4a2557f483..c9607f8c4f 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -15,6 +15,7 @@ With power-grid-model it is possible to perform two different types of calculati TODO: - What is the difference between power flow and state estimation - When should you use which? Maybe small example (physical, not code) +- Link to pf / se workshop? #### Power flow Power flow is a "what-if" based grid calculation that will calculate the node voltages and the power flow through the branches, based on assumed load/generation profiles. @@ -29,6 +30,48 @@ Output: - Power flow through branches #### State estimation +State estimation is a statistical calculation method that determines the most probable state of the grid, based on +network data and measurements. Measurements meaning power flow or voltage values with some kind of uncertainty, which were +either measured, estimated or forecasted. + +Input: +- Network data: topology + component attributes +- Power flow / voltage measurements with uncertainty + +Output: +- Node voltage magnitude and angle +- Power flow through branches +- Deviation between measurement values and estimated state + +In order to perform a state estimation the system should be observable. Simply said, observability means that the number of measurements +should be larger than or equal to the number of unknowns. For each node there are two unknowns, `u` and `u_angle`, so the following +equations should be met: + +$$ + \begin{eqnarray} + n_{measurements} & >= & n_{unknowns} + \end{eqnarray} +$$ + +Where + +$$ + \begin{eqnarray} + n_{unknowns} & = & 2 & \cdot & n_{unknowns} + \end{eqnarray} +$$ + +And + +$$ + \begin{eqnarray} + n_{\text{measurements}} = n_{\text{nodes_with_voltage_sensor_without_angle}} + 2 n_{\text{nodes_with_voltage_sensor_with_angle}} + 2 n_{\text{branches_with_power_sensor}} + 2 n_{\text{nodes_without_any_appliances_connected}} + 2 n_{\text{nodes_with_all_connected_appliances_measured_by_power_sensor}} + \end{eqnarray} +$$ + + + + ### Power flow algorithms Two types of power flow algorithms are implemented in power-grid-model; iterative algorithms (Newton-Raphson / Iterative current) and linear algorithms (Linear / Linear current). From 3862fc3af01027a248d3e224984bba898f891d3d Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 15:53:15 +0100 Subject: [PATCH 09/62] remove \text{} Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index c9607f8c4f..7a0f2a53f6 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -65,7 +65,7 @@ And $$ \begin{eqnarray} - n_{\text{measurements}} = n_{\text{nodes_with_voltage_sensor_without_angle}} + 2 n_{\text{nodes_with_voltage_sensor_with_angle}} + 2 n_{\text{branches_with_power_sensor}} + 2 n_{\text{nodes_without_any_appliances_connected}} + 2 n_{\text{nodes_with_all_connected_appliances_measured_by_power_sensor}} + n_{measurements} = n_{nodes_with_voltage_sensor_without_angle} + 2 n_{nodes_with_voltage_sensor_with_angle} + 2 n_{branches_with_power_sensor} + 2 n_{nodes_without_any_appliances_connected} + 2 n_{nodes_with_all_connected_appliances_measured_by_power_sensor} \end{eqnarray} $$ From 7c3be66ab5050246dbf5fdfad42cb46bf9152fc6 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 15:54:38 +0100 Subject: [PATCH 10/62] test \_ Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 7a0f2a53f6..50e55001aa 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -65,7 +65,7 @@ And $$ \begin{eqnarray} - n_{measurements} = n_{nodes_with_voltage_sensor_without_angle} + 2 n_{nodes_with_voltage_sensor_with_angle} + 2 n_{branches_with_power_sensor} + 2 n_{nodes_without_any_appliances_connected} + 2 n_{nodes_with_all_connected_appliances_measured_by_power_sensor} + n_{measurements} = n_{nodes\_with\_voltage\_sensor\_without\_angle} + 2 n_{nodes_with_voltage_sensor_with_angle} + 2 n_{branches_with_power_sensor} + 2 n_{nodes_without_any_appliances_connected} + 2 n_{nodes_with_all_connected_appliances_measured_by_power_sensor} \end{eqnarray} $$ From 528e95ae5b43d6fe79bc60851143d34bd5e6abec Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 16:00:51 +0100 Subject: [PATCH 11/62] try \text again Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 50e55001aa..131ba5e328 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -65,7 +65,7 @@ And $$ \begin{eqnarray} - n_{measurements} = n_{nodes\_with\_voltage\_sensor\_without\_angle} + 2 n_{nodes_with_voltage_sensor_with_angle} + 2 n_{branches_with_power_sensor} + 2 n_{nodes_without_any_appliances_connected} + 2 n_{nodes_with_all_connected_appliances_measured_by_power_sensor} + n_{\text{measurements}} = n_{\text{nodes\_with\_voltage\_sensor\_without\_angle}} + 2 n_{\text{nodes\_with\_voltage\_sensor\_with\_angle}} + 2 n_{\text{branches\_with\_power\_sensor}} + 2 n_{\text{nodes\_without\_any\_appliances\_connected}} + 2 n_{\text{nodes\_with\_all\_connected\_appliances\_measured\_by\_power\_sensor}} \end{eqnarray} $$ From c2571767c6a897482082d39bb09c6ce0059e2622 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 16:07:11 +0100 Subject: [PATCH 12/62] texttt Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 131ba5e328..d02016ca48 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -65,7 +65,7 @@ And $$ \begin{eqnarray} - n_{\text{measurements}} = n_{\text{nodes\_with\_voltage\_sensor\_without\_angle}} + 2 n_{\text{nodes\_with\_voltage\_sensor\_with\_angle}} + 2 n_{\text{branches\_with\_power\_sensor}} + 2 n_{\text{nodes\_without\_any\_appliances\_connected}} + 2 n_{\text{nodes\_with\_all\_connected\_appliances\_measured\_by\_power\_sensor}} + n_{\texttt{measurements}} = n_{\texttt{nodes\_with\_voltage\_sensor\_without\_angle}} + 2 n_{\texttt{nodes\_with\_voltage\_sensor\_with\_angle}} + 2 n_{\texttt{branches\_with\_power\_sensor}} + 2 n_{\texttt{nodes\_without\_any\_appliances\_connected}} + 2 n_{\texttt{nodes\_with\_all\_connected\_appliances\_measured\_by\_power\_sensor}} \end{eqnarray} $$ From 5eef26d6617bbe7fd03d4e8e5580f8596d248fd5 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 16:19:28 +0100 Subject: [PATCH 13/62] change last equation to text Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index d02016ca48..5a20dd8e74 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -57,17 +57,19 @@ Where $$ \begin{eqnarray} - n_{unknowns} & = & 2 & \cdot & n_{unknowns} + n_{unknowns} & = & 2 & \cdot & n_{nodes} \end{eqnarray} $$ -And +The number of measurements can be found by the sum of the following: +- number of nodes with a voltage sensor with magnitude only +- two times the number of nodes with a voltage sensor with magnitude and angle +- two times the number of nodes without appliances connected +- two times the number of nodes where all connected appliances are measured by a power sensor +- two times the number of branches with a power sensor -$$ - \begin{eqnarray} - n_{\texttt{measurements}} = n_{\texttt{nodes\_with\_voltage\_sensor\_without\_angle}} + 2 n_{\texttt{nodes\_with\_voltage\_sensor\_with\_angle}} + 2 n_{\texttt{branches\_with\_power\_sensor}} + 2 n_{\texttt{nodes\_without\_any\_appliances\_connected}} + 2 n_{\texttt{nodes\_with\_all\_connected\_appliances\_measured\_by\_power\_sensor}} - \end{eqnarray} -$$ +Note: enough measurements doesn't necessarily mean that the system is observable. The location of the measurements is also +of importance. From 4ff47d31c94371b134fff7b037fee0482e092e8e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 21 Nov 2022 16:41:27 +0100 Subject: [PATCH 14/62] comments about observability and singular matrix error Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 5a20dd8e74..22123c1a82 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -43,7 +43,8 @@ Output: - Power flow through branches - Deviation between measurement values and estimated state -In order to perform a state estimation the system should be observable. Simply said, observability means that the number of measurements +In order to perform a state estimation the system should be observable. If the system is not observable the calculation will +raise a singular matrix error. Simply said, observability means that the number of measurements should be larger than or equal to the number of unknowns. For each node there are two unknowns, `u` and `u_angle`, so the following equations should be met: @@ -69,7 +70,9 @@ The number of measurements can be found by the sum of the following: - two times the number of branches with a power sensor Note: enough measurements doesn't necessarily mean that the system is observable. The location of the measurements is also -of importance. +of importance. Also, there should be at least one voltage measurement. The [iterative linear](####iterativelinear) +state estimation algorithm assumes voltage angles to be zero when not given. This might result in the calculation succeeding, but giving +a faulty outcome instead of raising a singular matrix error. @@ -112,7 +115,8 @@ At the moment one state estimation algorithm is implemented: [iterative linear]( #### Iterative linear -TODO: extend the explanation of the algorithm. +TODO: extend the explanation of the algorithm. Mention that the algorithm will assume angles to be zero if not given. This might result in not having a +crash due to an unobservable system, but succeeding with the calculations and giving faulty results. Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method which converges to a true solution. [Matrix-prefactorization](./performance-guide.md#matrix-prefactorization) is possible. From 3d3a1bbc37e635eb2565b335c31164bea08ed1a1 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 22 Nov 2022 09:41:10 +0100 Subject: [PATCH 15/62] fix references Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 22123c1a82..0d2593e776 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -8,8 +8,8 @@ SPDX-License-Identifier: MPL-2.0 ## Calculation types With power-grid-model it is possible to perform two different types of calculation: -- [Power flow](###Power flow algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) -- [State estimation](###State estimation algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) +- [Power flow](###power-flow-algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) +- [State estimation](###state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) ### Calculation types explained TODO: @@ -70,7 +70,7 @@ The number of measurements can be found by the sum of the following: - two times the number of branches with a power sensor Note: enough measurements doesn't necessarily mean that the system is observable. The location of the measurements is also -of importance. Also, there should be at least one voltage measurement. The [iterative linear](####iterativelinear) +of importance. Also, there should be at least one voltage measurement. The [iterative linear](####iterative-linear) state estimation algorithm assumes voltage angles to be zero when not given. This might result in the calculation succeeding, but giving a faulty outcome instead of raising a singular matrix error. @@ -85,10 +85,10 @@ They can be used where approximate solutions are acceptable. The table below can | Algorithm | Speed | Accuracy | Algorithm call | |--------------------------------------------|----------|----------|---------------------------------------| -| [Newton-Raphson](####Newton-Raphson) | | ✔ | `CalculationMethod.newton_raphson` | -| [Iterative current](####Iterative current) | | ✔ | `CalculationMethod.iterative_current` | -| [Linear](####Linear) | ✔ | | `CalculationMethod.linear` | -| [Linear current](####Linear current) | ✔ | | `CalculationMethod.linear_current` | +| [Newton-Raphson](####newton-raphson) | | ✔ | `CalculationMethod.newton_raphson` | +| [Iterative current](####iterative-current) | | ✔ | `CalculationMethod.iterative_current` | +| [Linear](####linear) | ✔ | | `CalculationMethod.linear` | +| [Linear current](####linear-current) | ✔ | | `CalculationMethod.linear_current` | TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. Also include the mathematics/algorithms. @@ -111,7 +111,7 @@ Power flow calculation is done using the {py:class}`calculate_power_flow Date: Tue, 22 Nov 2022 10:00:22 +0100 Subject: [PATCH 16/62] remove excessive ### in reference Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 0d2593e776..f68b1f6f40 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -8,8 +8,8 @@ SPDX-License-Identifier: MPL-2.0 ## Calculation types With power-grid-model it is possible to perform two different types of calculation: -- [Power flow](###power-flow-algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) -- [State estimation](###state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) +- [Power flow](#power-flow-algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) +- [State estimation](#state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) ### Calculation types explained TODO: @@ -70,7 +70,7 @@ The number of measurements can be found by the sum of the following: - two times the number of branches with a power sensor Note: enough measurements doesn't necessarily mean that the system is observable. The location of the measurements is also -of importance. Also, there should be at least one voltage measurement. The [iterative linear](####iterative-linear) +of importance. Also, there should be at least one voltage measurement. The [iterative linear](#iterative-linear) state estimation algorithm assumes voltage angles to be zero when not given. This might result in the calculation succeeding, but giving a faulty outcome instead of raising a singular matrix error. @@ -83,12 +83,12 @@ Two types of power flow algorithms are implemented in power-grid-model; iterativ Iterative methods are more accurate and should thus be selected when an accurate solution is required. Linear approximation methods are many times faster than the iterative methods, in tradeoff to accuracy. They can be used where approximate solutions are acceptable. The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. -| Algorithm | Speed | Accuracy | Algorithm call | -|--------------------------------------------|----------|----------|---------------------------------------| -| [Newton-Raphson](####newton-raphson) | | ✔ | `CalculationMethod.newton_raphson` | -| [Iterative current](####iterative-current) | | ✔ | `CalculationMethod.iterative_current` | -| [Linear](####linear) | ✔ | | `CalculationMethod.linear` | -| [Linear current](####linear-current) | ✔ | | `CalculationMethod.linear_current` | +| Algorithm | Speed | Accuracy | Algorithm call | +|-----------------------------------------|----------|----------|---------------------------------------| +| [Newton-Raphson](#newton-raphson) | | ✔ | `CalculationMethod.newton_raphson` | +| [Iterative current](#iterative-current) | | ✔ | `CalculationMethod.iterative_current` | +| [Linear](#linear) | ✔ | | `CalculationMethod.linear` | +| [Linear current](#linear-current) | ✔ | | `CalculationMethod.linear_current` | TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. Also include the mathematics/algorithms. @@ -111,7 +111,7 @@ Power flow calculation is done using the {py:class}`calculate_power_flow Date: Tue, 22 Nov 2022 11:34:26 +0100 Subject: [PATCH 17/62] fix example ref Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index f68b1f6f40..63495751bf 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -8,8 +8,8 @@ SPDX-License-Identifier: MPL-2.0 ## Calculation types With power-grid-model it is possible to perform two different types of calculation: -- [Power flow](#power-flow-algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) -- [State estimation](#state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](ex_state_est) +- [Power flow](#power-flow-algorithms): a "what-if" scenario calculation. This calculation can be performed by using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](../examples/Power%20Flow%20Example.ipynb) +- [State estimation](#state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](../examples/State%20Estimation%20Example.ipynb) ### Calculation types explained TODO: From 3424cd125a3d4fef186edc39b7a59949420afd82 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 22 Nov 2022 11:37:25 +0100 Subject: [PATCH 18/62] remove old docs Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 63495751bf..04698451e0 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -105,10 +105,6 @@ It will be more accurate when most of the load/generation types are of constant #### Linear current It will be more accurate when most of the load/generation types are constant power or constant current. Batch calculations here will be faster because matrix prefactorization is possible. -## Power-flow calculation - -Power flow calculation is done using the {py:class}`calculate_power_flow ` method. An example of usage of the power-flow calculation function is given in [Power flow Example](ex_power_flow) - ### State estimation algorithms At the moment one state estimation algorithm is implemented: [iterative linear](#iterative-linear). From ed709abee03be34bcf2de45046f5d11ca6363ef5 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 22 Nov 2022 11:39:40 +0100 Subject: [PATCH 19/62] remove TODO Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 04698451e0..4f514e0def 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -12,10 +12,6 @@ With power-grid-model it is possible to perform two different types of calculati - [State estimation](#state-estimation-algorithms): a statistical method that calculates the most probabilistic state of the grid, given sensor values with an uncertainty. This calculation can be performed by using the {py:class}`calculate_state_estimation ` method. An example of usage of the power-flow calculation function is given in [State Estimation Example](../examples/State%20Estimation%20Example.ipynb) ### Calculation types explained -TODO: -- What is the difference between power flow and state estimation -- When should you use which? Maybe small example (physical, not code) -- Link to pf / se workshop? #### Power flow Power flow is a "what-if" based grid calculation that will calculate the node voltages and the power flow through the branches, based on assumed load/generation profiles. From 26dbe25698676167c49824310193f95c987cf2b0 Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Thu, 24 Nov 2022 08:35:30 +0100 Subject: [PATCH 20/62] add content Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 3d7a7aa312..257c5d4056 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -36,13 +36,35 @@ TODO: for each of the algorithms give a brief explanation of the algorithm and i Traditional Newton-Raphson method. #### Iterative Current -Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . + +This algorithm is a jacobi like method for powerflow analysis. + +It has linear convergence as opposed to quadratic for newton-raphson. This means that the number of iterations will be greater. Newton-Raphson would also be more robust in achieving convergence in case of greater meshed configurations. However, Iterative current algorithm can be faster most of the time. + +The algorithm is as follows: +1. Build Y bus matrix +2. Initialization $U_N^0$ +3. Calculate injected currents: $I_N^i$ for $i^{th}$ iteration. The injected currents are calculated as per ZIP model of loads and generation using $U_N$. +$$ I_N = \overline{S_{Z}} \cdot U_{N} + \overline{(\frac{S_{I}}{U_{N}})} \cdot |U_{N}| + \overline{(\frac{S_{P}}{U_N})} +$$ +4. Solve linear equation: $YU_N^i = I_N^i$ +5. Check convergence: If maximum voltage deviation from previous iteration is greater than the tolerance setting (ie. $u^{(i-1)}_\sigma > u_\epsilon$), then go back to step 3. + +Compared to newton-raphson, it only needs to calculate injected currents before solving linear equations. This is more straightforward than calculating the jacobian. +Factorizing the matrix of linear equation is the most computationally heavy task. +The Y bus matrix here does not change across iterations which means it only needs to be factorized once to solve the linear equations in all iterations. The Y bus matrix is also unchanged in certain batch calculations like timeseries calculations. Thus the same factorization is used for all batches as well. + #### Linear It will be more accurate when most of the load/generation types are of constant impedance. #### Linear current -It will be more accurate when most of the load/generation types are constant power or constant current. Batch calculations here will be faster because matrix prefactorization is possible. + +**This algorithm is essentially a single iteration of [Iterative Current](calculations.md#iterative-current).** It will be more accurate when most of the load/generation types resemble constant current. For same reasons mentioned in [Iterative Current](calculations.md#iterative-current), batch calculations here will be faster because matrix prefactorization is possible. + +In practical grids most loads and generations correspond to the constant power type. Linear current would give a better approximation than [Linear](calculations.md#linear) in such case. This is because we approximate the load as current instead of impedance. +There is a correlation in voltage error of approximation with respect to the actual voltage for all approximations. They are most accurate when the actual voltages are close to 1 p.u. and the error increases as we deviate from this level. +When we approximate the load as impedance at 1 p.u., the voltage error has quadratic relation to the actual voltage. When it is approximated as a current at 1 p.u., the voltage error is only linearly dependent in comparison. ## Power-flow calculation From 55716c54bd537ea37ccc82475a798bac099c18dd Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 13:43:55 +0100 Subject: [PATCH 21/62] general introduction power flow Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 49cf816266..38bacb93cd 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -31,8 +31,28 @@ They can be used where approximate solutions are acceptable. The table below can TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. Also include the mathematics/algorithms. +The nodal equations of a power system network can be written as: + +$$ + \begin{eqnarray} + I & = Y_{bus}V + \end{eqnarray} +$$ + +Where $I$ is the $N$ vector of source currents injected into each bus and $V$ is the $N$ vector of bus voltages. The complex power +delivered to bus $k$ is: + +$$ + \begin{eqnarray} + S_{k} & = P_k + jQ_k & = V_{k} I_{k}^{*} + \end{eqnarray} +$$ + +Power flow equations are based on solving the nodal equations above to obtain the voltage and voltage angle at each node +and the real and reactive power flow through the branches. + #### Newton-Raphson -Traditional Newton-Raphson method. +This is the traditional method for power flow calculations. #### Iterative Current Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . From 00ace4e97088ad1b30d8e8a4abc20d8883cab364 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 14:28:15 +0100 Subject: [PATCH 22/62] power flow buses Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 38bacb93cd..8d8a327e5a 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -49,7 +49,11 @@ $$ $$ Power flow equations are based on solving the nodal equations above to obtain the voltage and voltage angle at each node -and the real and reactive power flow through the branches. +and then obtaining the real and reactive power flow through the branches. The following bus types can be present in the system: + +- Slack bus: the reference bus with known voltage and angle; in power-grid-model referred to as the [source](./components.md#source). +- Load bus: a bus with known $P$ and $Q$. +- Voltage controlled bus: a bus with known $P$ and $V$. #### Newton-Raphson This is the traditional method for power flow calculations. From 9eea822fab661bf4135425889c2e95bc8c9e733e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 15:29:11 +0100 Subject: [PATCH 23/62] test latex vec Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 8d8a327e5a..7f164dc9a1 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -56,7 +56,25 @@ and then obtaining the real and reactive power flow through the branches. The fo - Voltage controlled bus: a bus with known $P$ and $V$. #### Newton-Raphson -This is the traditional method for power flow calculations. +This is the traditional method for power flow calculations. This method uses a Taylor series, ignoring the higher order +terms, to solve the nonlinear set of equations: + +$$ + \begin{eqnarray} + f_{x} & = y + \end{eqnarray} +$$ + +Where: + +$$ + \begin{eqnarray} + x = \begin{bmatrix} + \delta \\ + V + \end{bmatrix} + \end{eqnarray} +$$ #### Iterative Current Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . From 981f64e53f5c1fabe4dedecce70657dbbda91e4e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 15:32:20 +0100 Subject: [PATCH 24/62] extend eq Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 7f164dc9a1..3477e00fa3 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -61,7 +61,7 @@ terms, to solve the nonlinear set of equations: $$ \begin{eqnarray} - f_{x} & = y + f(x) & = y \end{eqnarray} $$ @@ -72,6 +72,14 @@ $$ x = \begin{bmatrix} \delta \\ V + \end{bmatrix} = + \begin{bmatrix} + \delta_2 \\ + \vdots \\ + \delta_N + V_2 + \vdots \\ + V_N \end{bmatrix} \end{eqnarray} $$ From 7ebd7813c142506d1a96367860e1ed9f8c609895 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 15:33:04 +0100 Subject: [PATCH 25/62] fix enter Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 3477e00fa3..79ea2ec6f8 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -76,8 +76,8 @@ $$ \begin{bmatrix} \delta_2 \\ \vdots \\ - \delta_N - V_2 + \delta_N \\ + V_2 \\ \vdots \\ V_N \end{bmatrix} From 0939247daf7d619851da09b7c034be6deddb8123 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 15:36:18 +0100 Subject: [PATCH 26/62] add y Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 79ea2ec6f8..7657cf97aa 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -81,6 +81,19 @@ $$ \vdots \\ V_N \end{bmatrix} + \quad\text{and}\quad + y = \begin{bmatrix} + P \\ + Q + \end{bmatrix} = + \begin{bmatrix} + P_2 \\ + \vdots \\ + P_N \\ + Q_2 \\ + \vdots \\ + Q_N + \end{bmatrix} \end{eqnarray} $$ From dba9192feececac92bbcc7d83a5e1938684c75ea Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 15:39:20 +0100 Subject: [PATCH 27/62] add f(x) Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 7657cf97aa..ab51df2ac4 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -94,6 +94,19 @@ $$ \vdots \\ Q_N \end{bmatrix} + \quad\text{and}\quad + f(x) = \begin{bmatrix} + P(x) \\ + Q(x) + \end{bmatrix} = + \begin{bmatrix} + P_{2}(x) \\ + \vdots \\ + P_{N}(x) \\ + Q_{2}(x) \\ + \vdots \\ + Q_{N}(x) + \end{bmatrix} \end{eqnarray} $$ From 226699350f6be3f3444743120210c7df0b9178b4 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 25 Nov 2022 16:42:42 +0100 Subject: [PATCH 28/62] temp save Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index ab51df2ac4..0ff084ec30 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -57,7 +57,7 @@ and then obtaining the real and reactive power flow through the branches. The fo #### Newton-Raphson This is the traditional method for power flow calculations. This method uses a Taylor series, ignoring the higher order -terms, to solve the nonlinear set of equations: +terms, to solve the nonlinear set of equations iteratively: $$ \begin{eqnarray} @@ -110,6 +110,29 @@ $$ \end{eqnarray} $$ +As can be seen in the equations above $\delta_1$ and $V_1$ are omitted, because they are known for the slack bus. +In each iteration $i$ the following equation is solved: + +$$ + \begin{eqnarray} + J(i) \Delta x(i) & = \Delta y(i) + \end{eqnarray} +$$ + +Where + +$$ + \begin{eqnarray} + \Delta x(i) & = x(i+1) - x(i) + \quad\text{and}\quad + \Delta y(i) & = y - f(x(i)) + \end{eqnarray} +$$ + +$J$ is the [Jacobian](https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant), a matrix of partial derivatives: + +TODO: write jacobian + #### Iterative Current Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . From 07fd6b3277584e29550b7e500596d90e069578ca Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Sun, 27 Nov 2022 19:19:24 +0100 Subject: [PATCH 29/62] make edits Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 257c5d4056..09089341f0 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -38,8 +38,7 @@ Traditional Newton-Raphson method. #### Iterative Current This algorithm is a jacobi like method for powerflow analysis. - -It has linear convergence as opposed to quadratic for newton-raphson. This means that the number of iterations will be greater. Newton-Raphson would also be more robust in achieving convergence in case of greater meshed configurations. However, Iterative current algorithm can be faster most of the time. +It has linear convergence as opposed to quadratic convergence in newton-raphson method. This means that the number of iterations will be greater. Newton-Raphson would also be more robust in achieving convergence in case of greater meshed configurations. However, Iterative current algorithm will be faster most of the time. The algorithm is as follows: 1. Build Y bus matrix @@ -51,8 +50,8 @@ $$ 5. Check convergence: If maximum voltage deviation from previous iteration is greater than the tolerance setting (ie. $u^{(i-1)}_\sigma > u_\epsilon$), then go back to step 3. Compared to newton-raphson, it only needs to calculate injected currents before solving linear equations. This is more straightforward than calculating the jacobian. -Factorizing the matrix of linear equation is the most computationally heavy task. -The Y bus matrix here does not change across iterations which means it only needs to be factorized once to solve the linear equations in all iterations. The Y bus matrix is also unchanged in certain batch calculations like timeseries calculations. Thus the same factorization is used for all batches as well. + +Factorizing the matrix of linear equation is the most computationally heavy task. The Y bus matrix here does not change across iterations which means it only needs to be factorized once to solve the linear equations in all iterations. The Y bus matrix is also unchanged in certain batch calculations like timeseries calculations. Thus the same factorization is used for all batches as well. #### Linear @@ -60,7 +59,8 @@ It will be more accurate when most of the load/generation types are of constant #### Linear current -**This algorithm is essentially a single iteration of [Iterative Current](calculations.md#iterative-current).** It will be more accurate when most of the load/generation types resemble constant current. For same reasons mentioned in [Iterative Current](calculations.md#iterative-current), batch calculations here will be faster because matrix prefactorization is possible. +**This algorithm is essentially a single iteration of [Iterative Current](calculations.md#iterative-current).** It will be a better approximation when most of the load/generation types resemble constant current. Similar to [Iterative Current](calculations.md#iterative-current), batch calculations like timeseries, here will also be faster. The reason is the same that the Y bus matrix does not change across batches and the same factorization would be used. + In practical grids most loads and generations correspond to the constant power type. Linear current would give a better approximation than [Linear](calculations.md#linear) in such case. This is because we approximate the load as current instead of impedance. There is a correlation in voltage error of approximation with respect to the actual voltage for all approximations. They are most accurate when the actual voltages are close to 1 p.u. and the error increases as we deviate from this level. From a6812b3bc9962a9e85e6d2c1c0ce38af031b1585 Mon Sep 17 00:00:00 2001 From: Tony Xiang Date: Mon, 28 Nov 2022 13:07:35 +0100 Subject: [PATCH 30/62] Silence deprecated declaration warning from boost. Signed-off-by: Tony Xiang --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bf396cc21..c37b08f752 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ if(WIN32) else() add_compile_options(-Wall -Wextra -pedantic -Werror) add_compile_options(-Wno-deprecated-copy) # bug in boost + add_compile_options(-Wno-deprecated-declarations) # bug in boost if(UNIX AND NOT APPLE) # test coverage for debug build in linux, if specified if ((CMAKE_BUILD_TYPE STREQUAL "Debug") AND (DEFINED POWER_GRID_MODEL_COVERAGE) AND (POWER_GRID_MODEL_COVERAGE EQUAL 1)) From 12ed23527b2c96969e654356a40c0616a1012932 Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Wed, 30 Nov 2022 09:29:58 +0100 Subject: [PATCH 31/62] add content batch Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 3d7a7aa312..9beb6eaa75 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -61,11 +61,24 @@ Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method ## Batch Calculations +Usually, a single powerflow calculation would not be enough to get insights in the grid. +Any form of multiple number of calculations can be carried out in power-grid-model using batch calculations. +Batches are not restricted to any particular types of calculations like timeseries or contingency analysis. +They can be of both of them combined, hosting capacity calculations, monte-carlo simulations or any other form of multiple calculations. +The framework of creating the batches remains the same. +The attributes of each component which can be updated over batches are mentioned in [Components](components.md). +An example of batch calculation of timeseries and contingency analysis is given in [Power Flow Example](../examples/Power%20Flow%20Example.ipynb#batch-calculation.md) + + + + + TODO, add explanation on batch calculations: - when to use batch calculations - what are the batch options - how to use it - something else? +- independent batches ```{warning} From 9b54e744b227c1c43d025460b876d9c0b2e45438 Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Thu, 1 Dec 2022 08:47:58 +0100 Subject: [PATCH 32/62] add batch types doc Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 46 +++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 9beb6eaa75..bd2eeb8aad 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -61,26 +61,46 @@ Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method ## Batch Calculations -Usually, a single powerflow calculation would not be enough to get insights in the grid. +Usually, a single power-flow or state estimation calculation would not be enough to get insights in the grid. Any form of multiple number of calculations can be carried out in power-grid-model using batch calculations. -Batches are not restricted to any particular types of calculations like timeseries or contingency analysis. -They can be of both of them combined, hosting capacity calculations, monte-carlo simulations or any other form of multiple calculations. +Batches are not restricted to any particular types of calculations like timeseries or contingency analysis or their combination. +They can be used for determining hosting/loading capacity, determining optimal tap positions, estimating system losses, monte-carlo simulations or any other form of multiple calculations required in a power-flow study. The framework of creating the batches remains the same. The attributes of each component which can be updated over batches are mentioned in [Components](components.md). -An example of batch calculation of timeseries and contingency analysis is given in [Power Flow Example](../examples/Power%20Flow%20Example.ipynb#batch-calculation.md) +An example of batch calculation of timeseries and contingency analysis is given in [Power Flow Example](../examples/Power%20Flow%20Example.ipynb) +The same method `calculate_power_flow` to calculate a number of scenarios in one go. +To do this, you need to supply a `update_data` argument. +This argument contains a dictionary of 2D update arrays (one array per component type). +The performance for different batches vary. power-grid-model automatically makes efficient calculations wherever possible in case of [independent batches](calculations.md#independent-batch-dataset) and [caching topology](calculations.md#caching-topology). +### Independent Batch dataset +There are two ways to specify batches. -TODO, add explanation on batch calculations: -- when to use batch calculations -- what are the batch options -- how to use it -- something else? -- independent batches +- Only specify the objects and attributes that are changed in this batch. +Here original model is copied everytime for each batch. +- We specify all objects and attributes including the unchanged ones in one or more scenarios. i.e. The attributes to be updated have data for all batches. +This is an **independent** batch dataset (In a sense that each batch is independent of the original model input). +We do not need to keep a copy of the original model in such case. +The original model data is copied only once while we mutate over that data for all the batches. +This brings performance benefits. +### Caching topology -```{warning} -[Issue 79](https://github.com/alliander-opensource/power-grid-model/issues/79) -``` +To perform the calculations, a graph topology of the grid is to be constructed from the input data first. + +- If your batch scenarios are changing the switching status of branches and sources the base model is then kept as empty model without any internal cached graph/matrices. +Thus, the topology is constructed afresh for each batch from the input data. +N-1 check is a typical use case. + +- If all your batch scenarios do not change the switching status of branches and sources the model will re-use the pre-built internal graph/matrices for each calculation. +Time-series load profile calculation is a typical use case. This can bring performance benefits. + +### Parallel Computing + +The batch calculation supports shared memory multi-threading parallel computing. +The common internal states and variables are shared as much as possible to save memory usage and avoid copy. + +You can set `threading` parameter in `calculate_power_flow()` or `calculate_state_estimation()` to enable/disable parallel computing. From 33cc21cd4ba13ef7ee54be6e4601791e05ffa51a Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Thu, 1 Dec 2022 09:25:28 +0100 Subject: [PATCH 33/62] add content Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 7dcdfbd1e9..38446e8f41 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -77,7 +77,9 @@ a faulty outcome instead of raising a singular matrix error. ### Power flow algorithms Two types of power flow algorithms are implemented in power-grid-model; iterative algorithms (Newton-Raphson / Iterative current) and linear algorithms (Linear / Linear current). Iterative methods are more accurate and should thus be selected when an accurate solution is required. Linear approximation methods are many times faster than the iterative methods, in tradeoff to accuracy. -They can be used where approximate solutions are acceptable. The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. +They can be used where approximate solutions are acceptable. +Their accuracy is not explicitly calculated and may vary a lot. The user should have an intuition of their applicability based on the input grid configuration. +The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. | Algorithm | Speed | Accuracy | Algorithm call | |-----------------------------------------|----------|----------|---------------------------------------| @@ -112,7 +114,16 @@ Factorizing the matrix of linear equation is the most computationally heavy task #### Linear -It will be more accurate when most of the load/generation types are of constant impedance. + +This is an approximation method where we assume that all loads and generations are of constant impedance type regardless of their actual `LoadGenType`. +By doing so, we obtain huge performance benefits as the computation required is equivalent to a single iteration of the iterative methods. +It will be more accurate when most of the load/generation types are of constant impedance or the actual node voltages are close to 1 p.u. + +The algorithm is as follows: +1. Assume injected currents by loads $I_N=0$ since we model loads/generation as impedance. +Admittance of each load/generation is calculated from rated power as $y=-\overline{S}$ +2. Build Y bus matrix. Add the admittances of loads/generation to the diagonal elements. +3. Solve linear equation: $YU_N^i = I_N^i$ for $U_N$ #### Linear current From 5c3ca74104283d9d1fd8bd8a83cff29482c1b554 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 5 Dec 2022 10:16:08 +0100 Subject: [PATCH 34/62] Finish NR Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 0ff084ec30..509276a1e4 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -129,9 +129,15 @@ $$ \end{eqnarray} $$ -$J$ is the [Jacobian](https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant), a matrix of partial derivatives: - -TODO: write jacobian +$J$ is the [Jacobian](https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant), a matrix with all partial +derivatives of $\dfrac{\partial P}{\partial \delta}$, $\dfrac{\partial P}{\partial V}$, $\dfrac{\partial Q}{\partial \delta}$ +and $\dfrac{\partial Q}{\partial V}$. + +For each iteration the following steps are executed: +- Compute $\Delta y(i)$ +- Compute the Jacobian $J(i)$ +- Using Gaussian elimination and back substitution solve $J(i) \Delta x(i) & = \Delta y(i)$ for $\Delta x(i)$ +- Compute $x(i+1)$ from $\Delta x(i) & = x(i+1) - x(i)$ #### Iterative Current Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . From 227dd4f43f6c5dd6d72db098e6d4519deb44345c Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 5 Dec 2022 10:17:18 +0100 Subject: [PATCH 35/62] remove & Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 509276a1e4..a26aed1f18 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -136,8 +136,8 @@ and $\dfrac{\partial Q}{\partial V}$. For each iteration the following steps are executed: - Compute $\Delta y(i)$ - Compute the Jacobian $J(i)$ -- Using Gaussian elimination and back substitution solve $J(i) \Delta x(i) & = \Delta y(i)$ for $\Delta x(i)$ -- Compute $x(i+1)$ from $\Delta x(i) & = x(i+1) - x(i)$ +- Using Gaussian elimination and back substitution solve $J(i) \Delta x(i) = \Delta y(i)$ for $\Delta x(i)$ +- Compute $x(i+1)$ from $\Delta x(i) = x(i+1) - x(i)$ #### Iterative Current Newton-Raphson would be more robust in achieving convergence and require fewer iterations. However, Iterative current can be faster most times because it uses . From 152be4c4739989a1d8f4ad03f9d5e7f408acefc6 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 5 Dec 2022 16:36:08 +0100 Subject: [PATCH 36/62] some updates Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 9d70fa47cd..8ac6b3fb8f 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -145,7 +145,7 @@ The framework of creating the batches remains the same. The attributes of each component which can be updated over batches are mentioned in [Components](components.md). An example of batch calculation of timeseries and contingency analysis is given in [Power Flow Example](../examples/Power%20Flow%20Example.ipynb) -The same method `calculate_power_flow` to calculate a number of scenarios in one go. +The same method as for single calculations, `calculate_power_flow`, can be used to calculate a number of scenarios in one go. To do this, you need to supply a `update_data` argument. This argument contains a dictionary of 2D update arrays (one array per component type). @@ -168,7 +168,7 @@ This brings performance benefits. To perform the calculations, a graph topology of the grid is to be constructed from the input data first. - If your batch scenarios are changing the switching status of branches and sources the base model is then kept as empty model without any internal cached graph/matrices. -Thus, the topology is constructed afresh for each batch from the input data. +Thus, the topology is constructed for each batch from the input data. N-1 check is a typical use case. - If all your batch scenarios do not change the switching status of branches and sources the model will re-use the pre-built internal graph/matrices for each calculation. @@ -180,3 +180,7 @@ The batch calculation supports shared memory multi-threading parallel computing. The common internal states and variables are shared as much as possible to save memory usage and avoid copy. You can set `threading` parameter in `calculate_power_flow()` or `calculate_state_estimation()` to enable/disable parallel computing. + +- `threading=-1`, use sequential computing (default) +- `threading=0`, use number of threads available from the machine hardware (recommended) +- `threading>0`, set the number of threads you want to use \ No newline at end of file From a6652668535b458aeaa8339a7cef28a306fe45ad Mon Sep 17 00:00:00 2001 From: Nitish Bharambe Date: Tue, 6 Dec 2022 11:12:23 +0100 Subject: [PATCH 37/62] Add more explanation Signed-off-by: Nitish Bharambe --- docs/user_manual/calculations.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 8ac6b3fb8f..4e7431d88a 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -157,12 +157,37 @@ There are two ways to specify batches. - Only specify the objects and attributes that are changed in this batch. Here original model is copied everytime for each batch. + +Example: +``` +line_update = initialize_array('update', 'line', (3, 1)) +# for each mutation, only one object is specified +line_update['id'] = [[3], [5], [8]] +# specify only the changed status (switch off) of one line +line_update['from_status'] = [[0], [0], [0]] +line_update['to_status'] = [[0], [0], [0]] + +non_independent_update_data = {'line': line_update} +``` + - We specify all objects and attributes including the unchanged ones in one or more scenarios. i.e. The attributes to be updated have data for all batches. This is an **independent** batch dataset (In a sense that each batch is independent of the original model input). We do not need to keep a copy of the original model in such case. The original model data is copied only once while we mutate over that data for all the batches. This brings performance benefits. +Example: +``` +line_update = initialize_array('update', 'line', (3, 3)) # 3 scenarios, 3 objects (lines) +# below the same broadcasting trick +line_update['id'] = [[3, 5, 8]] +# fully specify the status of all lines, even it is the same as the base scenario +line_update['from_status'] = [[0, 1, 1], [1, 0, 1], [1, 1, 0]] +line_update['to_status'] = [[0, 1, 1], [1, 0, 1], [1, 1, 0]] + +independent_update_data = {'line': line_update} +``` + ### Caching topology To perform the calculations, a graph topology of the grid is to be constructed from the input data first. @@ -174,6 +199,11 @@ N-1 check is a typical use case. - If all your batch scenarios do not change the switching status of branches and sources the model will re-use the pre-built internal graph/matrices for each calculation. Time-series load profile calculation is a typical use case. This can bring performance benefits. +The topology is not cached when any of the switching statuses (`from_status`, `to_status` or `status`) of the following components are updated: +1. Branches: Lines, Links, Transformers +2. Branch3: Three winding transformer +3. Appliances: Sources + ### Parallel Computing The batch calculation supports shared memory multi-threading parallel computing. From e9a40048ee5d20b867b471f645891bee205075ad Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 7 Dec 2022 10:32:36 +0100 Subject: [PATCH 38/62] comments Nitish Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index e8e67da2b1..6a5904a1e3 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -106,12 +106,12 @@ $$ \end{eqnarray} $$ -Power flow equations are based on solving the nodal equations above to obtain the voltage and voltage angle at each node +Power flow equations are based on solving the nodal equations above to obtain the voltage magnitude and voltage angle at each node and then obtaining the real and reactive power flow through the branches. The following bus types can be present in the system: - Slack bus: the reference bus with known voltage and angle; in power-grid-model referred to as the [source](./components.md#source). - Load bus: a bus with known $P$ and $Q$. -- Voltage controlled bus: a bus with known $P$ and $V$. +- Voltage controlled bus: a bus with known $P$ and $V$. NOTE: this bus is not supported by power-grid-model yet. #### Newton-Raphson This is the traditional method for power flow calculations. This method uses a Taylor series, ignoring the higher order @@ -194,7 +194,7 @@ and $\dfrac{\partial Q}{\partial V}$. For each iteration the following steps are executed: - Compute $\Delta y(i)$ - Compute the Jacobian $J(i)$ -- Using Gaussian elimination and back substitution solve $J(i) \Delta x(i) = \Delta y(i)$ for $\Delta x(i)$ +- Using LU decomposition, solve $J(i) \Delta x(i) = \Delta y(i)$ for $\Delta x(i)$ - Compute $x(i+1)$ from $\Delta x(i) = x(i+1) - x(i)$ #### Iterative Current From 7da45bb6183a7f0a4f35a896ee3a4459f3a13283 Mon Sep 17 00:00:00 2001 From: Nitish Bharambe <78108900+nitbharambe@users.noreply.github.com> Date: Wed, 7 Dec 2022 16:28:56 +0100 Subject: [PATCH 39/62] add comments changes Signed-off-by: Nitish Bharambe <78108900+nitbharambe@users.noreply.github.com> --- docs/user_manual/calculations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 38446e8f41..37094af08c 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -118,6 +118,7 @@ Factorizing the matrix of linear equation is the most computationally heavy task This is an approximation method where we assume that all loads and generations are of constant impedance type regardless of their actual `LoadGenType`. By doing so, we obtain huge performance benefits as the computation required is equivalent to a single iteration of the iterative methods. It will be more accurate when most of the load/generation types are of constant impedance or the actual node voltages are close to 1 p.u. +When all the load/generation types are of constant impedance, power-grid-model uses Linear method regardless of the input provided by the user. The algorithm is as follows: 1. Assume injected currents by loads $I_N=0$ since we model loads/generation as impedance. From bf379162475b87e3988ba69a681f154331b35924 Mon Sep 17 00:00:00 2001 From: Nitish Bharambe <78108900+nitbharambe@users.noreply.github.com> Date: Wed, 7 Dec 2022 16:31:10 +0100 Subject: [PATCH 40/62] Update calculations.md Signed-off-by: Nitish Bharambe <78108900+nitbharambe@users.noreply.github.com> --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 37094af08c..bf8e1a4a65 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -118,7 +118,7 @@ Factorizing the matrix of linear equation is the most computationally heavy task This is an approximation method where we assume that all loads and generations are of constant impedance type regardless of their actual `LoadGenType`. By doing so, we obtain huge performance benefits as the computation required is equivalent to a single iteration of the iterative methods. It will be more accurate when most of the load/generation types are of constant impedance or the actual node voltages are close to 1 p.u. -When all the load/generation types are of constant impedance, power-grid-model uses Linear method regardless of the input provided by the user. +When all the load/generation types are of constant impedance, power-grid-model uses Linear method regardless of the input provided by the user. This is because this method will then be accurate and fastest. The algorithm is as follows: 1. Assume injected currents by loads $I_N=0$ since we model loads/generation as impedance. From d085ef16de5ca84f7c302a3479b98461bb783353 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 12 Dec 2022 14:48:21 +0100 Subject: [PATCH 41/62] SE introduction Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 8be182b909..c1d3b86852 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -242,6 +242,66 @@ When we approximate the load as impedance at 1 p.u., the voltage error has quadr ### State estimation algorithms +Weighted least squares (WLS) state estimation can be performed with poower-grid-model. +Given a grid with $N_b$ busesm the state variable column vector is defined as below. + + +$$ + \begin{eqnarray} + U = \begin{bmatrix} + U_1 \\ + U_2 \\ + \vdots \\ + U_{N_{b}} + \end{bmatrix} + \end{eqnarray} +$$ + +Where $U_i$ is the complex voltage phasor of the i-th bus. + +The goal os WLS state estimation is to evaluate the state variable with the highest likelihood given (pseudo) measurement input, +by solving: + +$$ + \begin{eqnarray} + min r(U) = \dfrac{1}{2} (f(U) - z)^H W (f(U) - z) + \end{eqnarray} +$$ + +Where: + +$$ + \begin{eqnarray} + x = \begin{bmatrix} + x_1 \\ + x_2 \\ + \vdots \\ + x_{N_{m}} + \end{bmatrix} = + f(U) + \quad\text{and}\quad + z = \begin{bmatrix} + z_1 \\ + z_2 \\ + \vdots \\ + z_{N_{m}} + \end{bmatrix} + \quad\text{and}\quad + W = \Sigma^{-1} = \begin{bmatrix} + \sigma_1^2 & 0 & \cdots & 0 \\ + 0 & \sigma_2^2 & \cdots & 0 \\ + \vdots & \vdots & \ddots &vdots \\ + 0 & 0 & \cdots & \sigma_{N_{m}}^2 + \end{bmatrix} ^-1 = + \begin{bmatrix} + w_1 & 0 & \cdots & 0 \\ + 0 & w_2 & \cdots & 0 \\ + \vdots & \vdots & \ddots &vdots \\ + 0 & 0 & \cdots & w_{N_{m}} + \end{bmatrix} + \end{eqnarray} +$$ + At the moment one state estimation algorithm is implemented: [iterative linear](#iterative-linear). #### Iterative linear From 7de2e046b0c49ceae6ba9d0a594bc2da4d69d897 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 12 Dec 2022 14:54:21 +0100 Subject: [PATCH 42/62] explanation of equations Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index c1d3b86852..bea195d8d7 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -292,16 +292,20 @@ $$ 0 & \sigma_2^2 & \cdots & 0 \\ \vdots & \vdots & \ddots &vdots \\ 0 & 0 & \cdots & \sigma_{N_{m}}^2 - \end{bmatrix} ^-1 = + \end{bmatrix} ^{-1} = \begin{bmatrix} w_1 & 0 & \cdots & 0 \\ 0 & w_2 & \cdots & 0 \\ - \vdots & \vdots & \ddots &vdots \\ + \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & w_{N_{m}} \end{bmatrix} \end{eqnarray} $$ +Where $x_i$ is the real value of the i-th measured quantity in complex form, $z_i$ is the i-th measured value in complex form, +$\sigma_i$ is the normalized standard deviation of the measurement error of the i-th measurement, $\Sigma$ is the normalized covariance matrix +and $W$ is the weighting factor matrix. + At the moment one state estimation algorithm is implemented: [iterative linear](#iterative-linear). #### Iterative linear From a060fb3c2ed7be8f66f3a0f5096069d4265b2b87 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Mon, 12 Dec 2022 16:17:15 +0100 Subject: [PATCH 43/62] aggregate measurements Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index bea195d8d7..20e0928c1f 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -308,6 +308,29 @@ and $W$ is the weighting factor matrix. At the moment one state estimation algorithm is implemented: [iterative linear](#iterative-linear). +There can be multiple sensors measuring the same physical quantity. For example, there can be multiple +voltage snesors on the same bus. The measurement data can be merged into one virtual measurement using a Kalman filter: + +$$ + \begin{eqnarray} + z = \dfrac{\sum_{k=1}^{N_{sensor}} z_k \sigma_k^{-2}}{\sum_{k=1}^{N_{sensor}} \sigma_k^{-2}} + \end{eqnarray} +$$ + +Where $z_k$ and $\sigma_k$ are the measured value and standard deviation of individual measurements. + +Multiple appliance measurements (power measurements) on one bus are aggregated as the total injection at the bus: + +$$ + \begin{eqnarray} + S = \sum_{k=1}^{N_{appliance}} S_k + \quad\text{and}\quad + \sigma^2 = \sum_{k=1}^{N_{appliance}} \sigma_k^2 + \end{eqnarray} +$$ + +Where $S_k$ and $\sigma_k$ are the measured value and the standard deviation of the individual appliances. + #### Iterative linear TODO: extend the explanation of the algorithm. Mention that the algorithm will assume angles to be zero if not given. This might result in not having a From fbcade64d55ec90d5d06cc1979fc25113eb98f92 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 10:59:14 +0100 Subject: [PATCH 44/62] linearize voltage Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 20e0928c1f..42adb2d475 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -242,8 +242,8 @@ When we approximate the load as impedance at 1 p.u., the voltage error has quadr ### State estimation algorithms -Weighted least squares (WLS) state estimation can be performed with poower-grid-model. -Given a grid with $N_b$ busesm the state variable column vector is defined as below. +Weighted least squares (WLS) state estimation can be performed with power-grid-model. +Given a grid with $N_b$ buses the state variable column vector is defined as below. $$ @@ -259,7 +259,7 @@ $$ Where $U_i$ is the complex voltage phasor of the i-th bus. -The goal os WLS state estimation is to evaluate the state variable with the highest likelihood given (pseudo) measurement input, +The goal of WLS state estimation is to evaluate the state variable with the highest likelihood given (pseudo) measurement input, by solving: $$ @@ -336,6 +336,24 @@ Where $S_k$ and $\sigma_k$ are the measured value and the standard deviation of TODO: extend the explanation of the algorithm. Mention that the algorithm will assume angles to be zero if not given. This might result in not having a crash due to an unobservable system, but succeeding with the calculations and giving faulty results. +Linear WLS requires all measurements to be linear. This is only possible is all measurements are phasor unit measurements, +which is not realistic in a distribution grid. Therefore, traditional measurements are linearized before the algorithm is performed: + +- Linear WLS requires a voltage phasor including a phase angle. Given that the phase shift in the distribution grid is very small, +it is assumed that the angle shift is zero plus the intrinsic phase shift of transformers. For a certain bus `i`, the voltage +magnitude measured at that bus is translated into voltage phasor: + +$$ + \begin{eqnarray} + \underline{U}_i = U_i \cdot e^{j \Theta_i} + \end{eqnarray} +$$ + +- Test layout + + + + Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method which converges to a true solution. [Matrix-prefactorization](./performance-guide.md#matrix-prefactorization) is possible. From 85363a862593940b7653a77c036c35c9ecf05ce0 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 10:59:52 +0100 Subject: [PATCH 45/62] small theta Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 42adb2d475..d4d307eeb6 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -345,7 +345,7 @@ magnitude measured at that bus is translated into voltage phasor: $$ \begin{eqnarray} - \underline{U}_i = U_i \cdot e^{j \Theta_i} + \underline{U}_i = U_i \cdot e^{j \theta_i} \end{eqnarray} $$ From 5584f7adeb408336e622946be6a8c9f991f0537e Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 11:01:57 +0100 Subject: [PATCH 46/62] test layout Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index d4d307eeb6..10c23e6325 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -349,6 +349,8 @@ $$ \end{eqnarray} $$ +Where $\theta_i$ is the intrinsic transformer phase shift. + - Test layout From 08430bf9a34a7fe0487fe0e0aa191b76f55bdc51 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 11:09:25 +0100 Subject: [PATCH 47/62] finish linearization of measurements Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 10c23e6325..869ecf495c 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -339,9 +339,9 @@ crash due to an unobservable system, but succeeding with the calculations and gi Linear WLS requires all measurements to be linear. This is only possible is all measurements are phasor unit measurements, which is not realistic in a distribution grid. Therefore, traditional measurements are linearized before the algorithm is performed: -- Linear WLS requires a voltage phasor including a phase angle. Given that the phase shift in the distribution grid is very small, +- Bus voltage: Linear WLS requires a voltage phasor including a phase angle. Given that the phase shift in the distribution grid is very small, it is assumed that the angle shift is zero plus the intrinsic phase shift of transformers. For a certain bus `i`, the voltage -magnitude measured at that bus is translated into voltage phasor: +magnitude measured at that bus is translated into a voltage phasor, where $\theta_i$ is the intrinsic transformer phase shift: $$ \begin{eqnarray} @@ -349,9 +349,24 @@ $$ \end{eqnarray} $$ -Where $\theta_i$ is the intrinsic transformer phase shift. +- Branch/shunt power flow: Linear WLS requires a complex current phasor. To make this translation, the voltage at the terminal should +also be measured, otherwise the nominal voltage with zero angle is used as an estimation. With the measured (linearized) voltage +phasor, the current phasor is calculated as follows: -- Test layout +$$ + \begin{eqnarray} + \underline{I} = (\underline{S}/\underline{U})^* + \end{eqnarray} +$$ + +- Bus power injection: Linear WLS requires a complex current phasor. Similar as above, if the bus voltage is not measured, +the nominal voltage with zero angle will be used as an estimation. The current phasor is calculated as follows: + +$$ + \begin{eqnarray} + \underline{I} = (\underline{S}/\underline{U})^* + \end{eqnarray} +$$ From 5daf8df0c5705b21aefed8425784d41da15c5943 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 13:31:57 +0100 Subject: [PATCH 48/62] initialization Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 869ecf495c..77456a4f69 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -368,7 +368,18 @@ $$ \end{eqnarray} $$ - +The assumption made in the linearization of measurements introduces a system error to the algorithm, because the phase shifts of +bus voltages are ignored in the input measurement data. This error is corrected by applying an iterative approach to the linear WLS +algorithm. In each iteration, the resulted voltage phase angle will be applied as the phase shift of the measured voltage phasor +for the next iteration: + +- Initialization: let $\underline{U}^{(k)}$ be the column vector of the estimated voltage phasor in the k-th iteration. Let Bus $s$ +be the slack bus, which is connected to the external network (source). $\underline{U}^{(0)}$ is initialized as follows: + - For bus $i$, if there is no voltage measurement, assign $\underline{U}^{(0)} = e^{j \theta_i}$, where $\theta_i$ is the intrinsic + transformer phase shift between Bus $i$ and Bus $s$. + - For bus $i$, if there is a voltage measurement, assign $\underline{U}^{(0)} = U_{meas,i}e^{j \theta_i}$, where $U_{meas,i}$ is + the measured voltage magnitude. +- Iteration proces: Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method which converges to a true From 1543b35bd7bd3dbd48b104585cb6e22a9555d965 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 14:48:43 +0100 Subject: [PATCH 49/62] iterative algorithm Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 77456a4f69..dc467128d1 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -333,9 +333,6 @@ Where $S_k$ and $\sigma_k$ are the measured value and the standard deviation of #### Iterative linear -TODO: extend the explanation of the algorithm. Mention that the algorithm will assume angles to be zero if not given. This might result in not having a -crash due to an unobservable system, but succeeding with the calculations and giving faulty results. - Linear WLS requires all measurements to be linear. This is only possible is all measurements are phasor unit measurements, which is not realistic in a distribution grid. Therefore, traditional measurements are linearized before the algorithm is performed: @@ -379,11 +376,25 @@ be the slack bus, which is connected to the external network (source). $\underli transformer phase shift between Bus $i$ and Bus $s$. - For bus $i$, if there is a voltage measurement, assign $\underline{U}^{(0)} = U_{meas,i}e^{j \theta_i}$, where $U_{meas,i}$ is the measured voltage magnitude. -- Iteration proces: - +- In iteration $k$, follow the steps below: + - Linearize the voltage measurements by using the phase angle of the calculated voltages of iteration $k-1$. + - Linearize the complex power flow measurements by using either the linearized voltage measurement if the bus is measured, or + the voltage phasor result from iteration $k-1$. + - Compute the temporary new voltage phasor $\underline{\tilde{U}}^{(k)}$ using the pre-factorized matrix. + [Matrix-prefactorization](./performance-guide.md#matrix-prefactorization) + - Normalize the voltage phasor angle by setting the angle of the slack bus to zero: + - If the maximum deviation between $\underline{U}^{(k)}$ and $\underline{U}^{(k-1)}$ is smaller than the error tolerance $\epsilon$, + stop the iteration. Otherwise, continue until the maximum number of iterations is reached. + +In the iteration process, the phase angle of voltages at each bus is updated using the last iteration; +the system error of the phase shift converges to zero. Because the matrix is pre-built and +pre-factorized, the computation cost of each iteration is much smaller than Newton-Raphson +method, where the Jacobian matrix needs to be constructed and factorized each time. + +NOTE: Since the algorithm will assume angles to be zero if not given, this might result in not having a +crash due to an unobservable system, but succeeding with the calculations and giving faulty results. -Algorithm call: `CalculationMethod.iterative_linear`. It is an iterative method which converges to a true - solution. [Matrix-prefactorization](./performance-guide.md#matrix-prefactorization) is possible. +Algorithm call: `CalculationMethod.iterative_linear`. ## Batch Calculations From 08ff44452f651f7da06501dd7791e89e6e46f252 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Wed, 14 Dec 2022 14:52:03 +0100 Subject: [PATCH 50/62] remove . Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index dc467128d1..64722d5f52 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -394,7 +394,7 @@ method, where the Jacobian matrix needs to be constructed and factorized each ti NOTE: Since the algorithm will assume angles to be zero if not given, this might result in not having a crash due to an unobservable system, but succeeding with the calculations and giving faulty results. -Algorithm call: `CalculationMethod.iterative_linear`. +Algorithm call: `CalculationMethod.iterative_linear` ## Batch Calculations From 214e4c30cff13c5d10004b0ed58d844ffe683a2b Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Fri, 16 Dec 2022 12:10:30 +0100 Subject: [PATCH 51/62] fix equations Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 64722d5f52..96f1c18875 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -248,23 +248,23 @@ Given a grid with $N_b$ buses the state variable column vector is defined as bel $$ \begin{eqnarray} - U = \begin{bmatrix} - U_1 \\ - U_2 \\ + \underline{U} = \begin{bmatrix} + \underline{U}_1 \\ + \underline{U}_2 \\ \vdots \\ - U_{N_{b}} + \underline{U}_{N_{b}} \end{bmatrix} \end{eqnarray} $$ -Where $U_i$ is the complex voltage phasor of the i-th bus. +Where $\underline{U}_i$ is the complex voltage phasor of the i-th bus. The goal of WLS state estimation is to evaluate the state variable with the highest likelihood given (pseudo) measurement input, by solving: $$ \begin{eqnarray} - min r(U) = \dfrac{1}{2} (f(U) - z)^H W (f(U) - z) + min r(\underline{U}) = \dfrac{1}{2} (f(\underline{U}) - \underline{z})^H W (f(\underline{U}) - \underline{z}) \end{eqnarray} $$ @@ -272,25 +272,25 @@ Where: $$ \begin{eqnarray} - x = \begin{bmatrix} - x_1 \\ - x_2 \\ + \underline{x} = \begin{bmatrix} + \underline{x}_1 \\ + \underline{x}_2 \\ \vdots \\ - x_{N_{m}} + \underline{x}_{N_{m}} \end{bmatrix} = - f(U) + f(\underline{U}) \quad\text{and}\quad - z = \begin{bmatrix} - z_1 \\ - z_2 \\ + \underline{z} = \begin{bmatrix} + \underline{z}_1 \\ + \underline{z}_2 \\ \vdots \\ - z_{N_{m}} + \underline{z}_{N_{m}} \end{bmatrix} \quad\text{and}\quad W = \Sigma^{-1} = \begin{bmatrix} \sigma_1^2 & 0 & \cdots & 0 \\ 0 & \sigma_2^2 & \cdots & 0 \\ - \vdots & \vdots & \ddots &vdots \\ + \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \sigma_{N_{m}}^2 \end{bmatrix} ^{-1} = \begin{bmatrix} @@ -302,7 +302,7 @@ $$ \end{eqnarray} $$ -Where $x_i$ is the real value of the i-th measured quantity in complex form, $z_i$ is the i-th measured value in complex form, +Where $\underline{x}_i$ is the real value of the i-th measured quantity in complex form, $\underline{z}_i$ is the i-th measured value in complex form, $\sigma_i$ is the normalized standard deviation of the measurement error of the i-th measurement, $\Sigma$ is the normalized covariance matrix and $W$ is the weighting factor matrix. @@ -323,7 +323,7 @@ Multiple appliance measurements (power measurements) on one bus are aggregated a $$ \begin{eqnarray} - S = \sum_{k=1}^{N_{appliance}} S_k + \underline{S} = \sum_{k=1}^{N_{appliance}} \underline{S}_k \quad\text{and}\quad \sigma^2 = \sum_{k=1}^{N_{appliance}} \sigma_k^2 \end{eqnarray} From 7f06c7809c52a956f1bd73dd4f72905724a86229 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 09:52:26 +0100 Subject: [PATCH 52/62] remove TODO Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 96f1c18875..3568e9fff3 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -88,9 +88,6 @@ The table below can be used to pick the right algorithm. Below the table a more | [Linear](#linear) | ✔ | | `CalculationMethod.linear` | | [Linear current](#linear-current) | ✔ | | `CalculationMethod.linear_current` | -TODO: for each of the algorithms give a brief explanation of the algorithm and in what cases this algorithm would be the prefered method. The old explanations are given, but they should be extended/improved. -Also include the mathematics/algorithms. - The nodal equations of a power system network can be written as: $$ From c63f1fc3418de7cff485da0f89eb413537eeefe2 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 09:55:09 +0100 Subject: [PATCH 53/62] Note Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 3568e9fff3..23a55c5e36 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -110,7 +110,7 @@ and then obtaining the real and reactive power flow through the branches. The fo - Slack bus: the reference bus with known voltage and angle; in power-grid-model referred to as the [source](./components.md#source). - Load bus: a bus with known $P$ and $Q$. -- Voltage controlled bus: a bus with known $P$ and $V$. NOTE: this bus is not supported by power-grid-model yet. +- Voltage controlled bus: a bus with known $P$ and $V$. Note: this bus is not supported by power-grid-model yet. #### Newton-Raphson This is the traditional method for power flow calculations. This method uses a Taylor series, ignoring the higher order From 560f2e7fe704e11aec03f8f06e2e0dede8151c03 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 10:07:56 +0100 Subject: [PATCH 54/62] update iterative current Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 23a55c5e36..7a4010237e 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -199,20 +199,26 @@ For each iteration the following steps are executed: #### Iterative Current This algorithm is a jacobi like method for powerflow analysis. -It has linear convergence as opposed to quadratic convergence in newton-raphson method. This means that the number of iterations will be greater. Newton-Raphson would also be more robust in achieving convergence in case of greater meshed configurations. However, Iterative current algorithm will be faster most of the time. +It has linear convergence as opposed to quadratic convergence in the Newton-Raphson method. This means that the number of iterations will be greater. Newton-Raphson would also be more robust in achieving convergence in case of greater meshed configurations. However, Iterative current algorithm will be faster most of the time. The algorithm is as follows: -1. Build Y bus matrix -2. Initialization $U_N^0$ +1. Build $Y_{bus}$ matrix +2. Initialization of $U_N^0$ 3. Calculate injected currents: $I_N^i$ for $i^{th}$ iteration. The injected currents are calculated as per ZIP model of loads and generation using $U_N$. -$$ I_N = \overline{S_{Z}} \cdot U_{N} + \overline{(\frac{S_{I}}{U_{N}})} \cdot |U_{N}| + \overline{(\frac{S_{P}}{U_N})} +$$ + \begin{eqnarray} + I_N = \overline{S_{Z}} \cdot U_{N} + \overline{(\frac{S_{I}}{U_{N}})} \cdot |U_{N}| + \overline{(\frac{S_{P}}{U_N})} + \end{eqnarray} $$ 4. Solve linear equation: $YU_N^i = I_N^i$ -5. Check convergence: If maximum voltage deviation from previous iteration is greater than the tolerance setting (ie. $u^{(i-1)}_\sigma > u_\epsilon$), then go back to step 3. +5. Check convergence: If maximum voltage deviation from the previous iteration is greater than the tolerance setting (ie. $u^{(i-1)}_\sigma > u_\epsilon$), then go back to step 3. -Compared to newton-raphson, it only needs to calculate injected currents before solving linear equations. This is more straightforward than calculating the jacobian. +The iterative current algorithm only needs to calculate injected currents before solving linear equations. +This is more straightforward than calculating the Jacobian, which was done in the Newton-Raphson algorithm. -Factorizing the matrix of linear equation is the most computationally heavy task. The Y bus matrix here does not change across iterations which means it only needs to be factorized once to solve the linear equations in all iterations. The Y bus matrix is also unchanged in certain batch calculations like timeseries calculations. Thus the same factorization is used for all batches as well. +Factorizing the matrix of linear equation is the most computationally heavy task. +The $Y_{bus}$ matrix here does not change across iterations which means it only needs to be factorized once to solve the linear equations in all iterations. +The $Y_{bus}$ matrix also remains unchanged in certain batch calculations like timeseries calculations. #### Linear From b71be34e1d2d7db98b8126988a173132cdea8a80 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 10:11:49 +0100 Subject: [PATCH 55/62] add note about linear Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 7a4010237e..53476c82dc 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -88,6 +88,9 @@ The table below can be used to pick the right algorithm. Below the table a more | [Linear](#linear) | ✔ | | `CalculationMethod.linear` | | [Linear current](#linear-current) | ✔ | | `CalculationMethod.linear_current` | +Note: When all the load/generation types are of constant impedance, power-grid-model uses the [Linear](#linear) method regardless of the input provided by the user. +This is because this method will then be accurate and fastest. + The nodal equations of a power system network can be written as: $$ From bdc8610f2334c4435d13da28f5d9d4635efcb0d4 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 10:14:18 +0100 Subject: [PATCH 56/62] try table ref Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 53476c82dc..5e94c916fb 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -81,12 +81,12 @@ They can be used where approximate solutions are acceptable. Their accuracy is not explicitly calculated and may vary a lot. The user should have an intuition of their applicability based on the input grid configuration. The table below can be used to pick the right algorithm. Below the table a more in depth explanation is given for each algorithm. -| Algorithm | Speed | Accuracy | Algorithm call | -|-----------------------------------------|----------|----------|---------------------------------------| -| [Newton-Raphson](#newton-raphson) | | ✔ | `CalculationMethod.newton_raphson` | -| [Iterative current](#iterative-current) | | ✔ | `CalculationMethod.iterative_current` | -| [Linear](#linear) | ✔ | | `CalculationMethod.linear` | -| [Linear current](#linear-current) | ✔ | | `CalculationMethod.linear_current` | +| Algorithm | Speed | Accuracy | Algorithm call | +|--------------------------------------------------|----------|----------|---------------------------------------| +| [Newton-Raphson](calculations.md#newton-raphson) | | ✔ | `CalculationMethod.newton_raphson` | +| [Iterative current](calculations.md#iterative-current) | | ✔ | `CalculationMethod.iterative_current` | +| [Linear](calculations.md#linear) | ✔ | | `CalculationMethod.linear` | +| [Linear current](calculations.md#linear-current) | ✔ | | `CalculationMethod.linear_current` | Note: When all the load/generation types are of constant impedance, power-grid-model uses the [Linear](#linear) method regardless of the input provided by the user. This is because this method will then be accurate and fastest. From b7100d4de52e506b9cd0abcab6cb9e2e2583d53f Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 10:22:15 +0100 Subject: [PATCH 57/62] update algorithms Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index 5e94c916fb..c12eb4e359 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -206,7 +206,7 @@ It has linear convergence as opposed to quadratic convergence in the Newton-Raph The algorithm is as follows: 1. Build $Y_{bus}$ matrix -2. Initialization of $U_N^0$ +2. Initialization of $U_N^0$ to $1$ plus the intrinsic phase shift of transformers 3. Calculate injected currents: $I_N^i$ for $i^{th}$ iteration. The injected currents are calculated as per ZIP model of loads and generation using $U_N$. $$ \begin{eqnarray} @@ -234,8 +234,8 @@ When all the load/generation types are of constant impedance, power-grid-model u The algorithm is as follows: 1. Assume injected currents by loads $I_N=0$ since we model loads/generation as impedance. Admittance of each load/generation is calculated from rated power as $y=-\overline{S}$ -2. Build Y bus matrix. Add the admittances of loads/generation to the diagonal elements. -3. Solve linear equation: $YU_N^i = I_N^i$ for $U_N$ +2. Build $Y{bus}$. Add the admittances of loads/generation to the diagonal elements. +3. Solve linear equation: $YU_N = I_N$ for $U_N$ #### Linear current From 4354dc7a491d85578f4704b93f362c32b15fcd07 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 11:35:21 +0100 Subject: [PATCH 58/62] all V/U -> U Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index c12eb4e359..ddfb094d97 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -95,16 +95,16 @@ The nodal equations of a power system network can be written as: $$ \begin{eqnarray} - I & = Y_{bus}V + I_N & = Y_{bus}U_N \end{eqnarray} $$ -Where $I$ is the $N$ vector of source currents injected into each bus and $V$ is the $N$ vector of bus voltages. The complex power +Where $I_N$ is the $N$ vector of source currents injected into each bus and $U_N$ is the $N$ vector of bus voltages. The complex power delivered to bus $k$ is: $$ \begin{eqnarray} - S_{k} & = P_k + jQ_k & = V_{k} I_{k}^{*} + S_{k} & = P_k + jQ_k & = U_{k} I_{k}^{*} \end{eqnarray} $$ @@ -113,7 +113,7 @@ and then obtaining the real and reactive power flow through the branches. The fo - Slack bus: the reference bus with known voltage and angle; in power-grid-model referred to as the [source](./components.md#source). - Load bus: a bus with known $P$ and $Q$. -- Voltage controlled bus: a bus with known $P$ and $V$. Note: this bus is not supported by power-grid-model yet. +- Voltage controlled bus: a bus with known $P$ and $U$. Note: this bus is not supported by power-grid-model yet. #### Newton-Raphson This is the traditional method for power flow calculations. This method uses a Taylor series, ignoring the higher order @@ -131,15 +131,15 @@ $$ \begin{eqnarray} x = \begin{bmatrix} \delta \\ - V + U \end{bmatrix} = \begin{bmatrix} \delta_2 \\ \vdots \\ \delta_N \\ - V_2 \\ + U_2 \\ \vdots \\ - V_N + U_N \end{bmatrix} \quad\text{and}\quad y = \begin{bmatrix} @@ -190,8 +190,8 @@ $$ $$ $J$ is the [Jacobian](https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant), a matrix with all partial -derivatives of $\dfrac{\partial P}{\partial \delta}$, $\dfrac{\partial P}{\partial V}$, $\dfrac{\partial Q}{\partial \delta}$ -and $\dfrac{\partial Q}{\partial V}$. +derivatives of $\dfrac{\partial P}{\partial \delta}$, $\dfrac{\partial P}{\partial U}$, $\dfrac{\partial Q}{\partial \delta}$ +and $\dfrac{\partial Q}{\partial U}$. For each iteration the following steps are executed: - Compute $\Delta y(i)$ From 46a83ec1f70b6089625573d676daddab7379a3a5 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 11:41:37 +0100 Subject: [PATCH 59/62] reference for 4 hashes Signed-off-by: Peter Salemink --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 2f4008b4c4..3f8679ed2f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,7 +56,7 @@ # -- myst parser and myst_nb config ------------------------------------------------------ # label references for depth of headers: label name in anchor slug structure -myst_heading_anchors = 3 +myst_heading_anchors = 4 # execute jupter notebooks output before building webpage jupyter_execute_notebooks = "off" # Extentions in myst From 11d834621ffcd13fbd3e3124af938c1a2878f5bd Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 14:36:16 +0100 Subject: [PATCH 60/62] . Signed-off-by: Peter Salemink --- docs/user_manual/calculations.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/user_manual/calculations.md b/docs/user_manual/calculations.md index ddfb094d97..284d69671c 100644 --- a/docs/user_manual/calculations.md +++ b/docs/user_manual/calculations.md @@ -239,7 +239,10 @@ Admittance of each load/generation is calculated from rated power as $y=-\overli #### Linear current -**This algorithm is essentially a single iteration of [Iterative Current](calculations.md#iterative-current).** It will be a better approximation when most of the load/generation types resemble constant current. Similar to [Iterative Current](calculations.md#iterative-current), batch calculations like timeseries, here will also be faster. The reason is the same that the Y bus matrix does not change across batches and the same factorization would be used. +**This algorithm is essentially a single iteration of [Iterative Current](calculations.md#iterative-current).** +This approximation method will give better results when most of the load/generation types resemble constant current. +Similar to [Iterative Current](calculations.md#iterative-current), batch calculations like timeseries will also be faster. +The reason is the same: the $Y_{bus}$ matrix does not change across batches and the same factorization would be used. In practical grids most loads and generations correspond to the constant power type. Linear current would give a better approximation than [Linear](calculations.md#linear) in such case. This is because we approximate the load as current instead of impedance. From 456fdff06b9e5e0faec66f78d96d8d02ac72bac0 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 14:42:33 +0100 Subject: [PATCH 61/62] no sensor on link Signed-off-by: Peter Salemink --- docs/user_manual/components.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index 802a446ae9..c2cef4315f 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -84,7 +84,8 @@ also modeled as `line`. A `line` can only connect two nodes with the same rated `link` is a {hoverxreftooltip}`user_manual/components:branch` which usually represents a short internal cable/connection between two busbars inside a substation. It has a very high admittance (small impedance) which is set to a fixed per-unit value -(equivalent to 10e6 siemens for 10kV network). There is no additional attribute for `link`. +(equivalent to 10e6 siemens for 10kV network). Therefore, it is chosen by design that no sensors can be connected to a `link`. +There is no additional attribute for `link`. ### Transformer @@ -341,11 +342,13 @@ The table below shows a list of attributes. `power_sensor` is an abstract class for symmetric and asymmetric power sensor and is derived from {hoverxreftooltip}`user_manual/components:sensor`. It measures the active/reactive power flow of a terminal. The terminal is -either connecting an `appliance` and a `node`, or connecting the from/to end of a `branch` and a `node`. In case of a +either connecting an `appliance` and a `node`, or connecting the from/to end of a `branch` (except `link`) and a `node`. In case of a terminal between an `appliance` and a `node`, the power {hoverxreftooltip}`user_manual/data-model:Reference Direction` in the measurement data is the same as the reference direction of the `appliance`. For example, if a `power_sensor` is measuring a `source`, a positive `p_measured` indicates that the active power flows from the source to the node. +Note: due to the high admittance of a `link` it is chosen that a power sensor cannot be connected to a `link`, even though a link is a `branch` + | name | data type | unit | description | required | input | update | output | valid values | | --- | --- | --- | --- | :---: | :---: | :---: | :---: |:---------------------------------------------------:| | `measured_terminal_type` | {py:class}`MeasuredTerminalType ` | - | indicate if it measures an `appliance` or a `branch`| ✔ | ✔ | ❌ | ❌ | the terminal type should match the `measured_object` | From 3a90f748237b672abe94e7147570aad4fcef3439 Mon Sep 17 00:00:00 2001 From: Peter Salemink Date: Tue, 20 Dec 2022 14:47:14 +0100 Subject: [PATCH 62/62] add to enum Signed-off-by: Peter Salemink --- docs/user_manual/components.md | 4 ++-- src/power_grid_model/enum.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/user_manual/components.md b/docs/user_manual/components.md index c2cef4315f..a62bbc9399 100644 --- a/docs/user_manual/components.md +++ b/docs/user_manual/components.md @@ -84,7 +84,7 @@ also modeled as `line`. A `line` can only connect two nodes with the same rated `link` is a {hoverxreftooltip}`user_manual/components:branch` which usually represents a short internal cable/connection between two busbars inside a substation. It has a very high admittance (small impedance) which is set to a fixed per-unit value -(equivalent to 10e6 siemens for 10kV network). Therefore, it is chosen by design that no sensors can be connected to a `link`. +(equivalent to 10e6 siemens for 10kV network). Therefore, it is chosen by design that no sensors can be coupled to a `link`. There is no additional attribute for `link`. ### Transformer @@ -347,7 +347,7 @@ terminal between an `appliance` and a `node`, the power {hoverxreftooltip}`user_ measurement data is the same as the reference direction of the `appliance`. For example, if a `power_sensor` is measuring a `source`, a positive `p_measured` indicates that the active power flows from the source to the node. -Note: due to the high admittance of a `link` it is chosen that a power sensor cannot be connected to a `link`, even though a link is a `branch` +Note: due to the high admittance of a `link` it is chosen that a power sensor cannot be coupled to a `link`, even though a link is a `branch` | name | data type | unit | description | required | input | update | output | valid values | | --- | --- | --- | --- | :---: | :---: | :---: | :---: |:---------------------------------------------------:| diff --git a/src/power_grid_model/enum.py b/src/power_grid_model/enum.py index ccc4d32e4a..bb80c77c6a 100644 --- a/src/power_grid_model/enum.py +++ b/src/power_grid_model/enum.py @@ -69,11 +69,11 @@ class MeasuredTerminalType(IntEnum): branch_from = 0 """ - Measuring the from-terminal between a branch and a node + Measuring the from-terminal between a branch (except link) and a node """ branch_to = 1 """ - Measuring the to-terminal between a branch and a node + Measuring the to-terminal between a branch (except link) and a node """ source = 2 """