Skip to content

Commit 794e15e

Browse files
committed
add basic lu solver documentation
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
1 parent 24eaaf9 commit 794e15e

File tree

4 files changed

+173
-28
lines changed

4 files changed

+173
-28
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!--
2+
SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
3+
4+
SPDX-License-Identifier: MPL-2.0
5+
-->
6+
7+
# Algorithms
8+
9+
```{toctree}
10+
self
11+
lu-solver
12+
```
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<!--
2+
SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
3+
4+
SPDX-License-Identifier: MPL-2.0
5+
-->
6+
7+
# LU Solver
8+
9+
Power system equations can be modeled as matrix equations. A matrix equation solver is therefore
10+
key to the power grid model.
11+
12+
This section documents the need for a custom sparse LU solver and its implementation.
13+
14+
## Background
15+
16+
The choice for the matrix equation solver type heavily leans on the need for
17+
[performance](#performance-considerations), the
18+
[topological structure](#topological-structure) of the grid and the
19+
[properties of the equations](#power-system-equation-properties). They are documented here.
20+
21+
### Performance considerations
22+
23+
There is a large variety of usages of the power grid model that require good performance. This
24+
imposes some constraints on the algorithms that can be used.
25+
26+
* Highly accurate and fast calculations are needed for very large grids. This means that direct
27+
methods are strongly preferred, and approximate methods can only be used when there is no other
28+
alternative, and only if can be iteratively refined with a fast convergence rate.
29+
* Sometimes, very many repetitive calculations are required, e.g., for time series. In those cases,
30+
separating the decomposition of a matrix and solving two systems of equations separately can give
31+
major performance boosts.
32+
33+
### Topological structure
34+
35+
Distribution grids consist of substations that distribute power in a region. This can be represented
36+
in a topological way as vertices and edges. As a consequence of the locality of Kirchoff's laws,
37+
power system equations also take on the same topological structure in block-matrix equation form.
38+
39+
#### Sparsity
40+
41+
It is common that a substation is fed by a single upstream substation, i.e., most grids are operated
42+
in a tree-like structure. Meshed grid operations are rare, and even when they do happen, it is
43+
usually only for a small section of the grid. All this gives rise to extremely sparse topologies
44+
and, as a result, extremely sparse matrix equations with a block structure.
45+
46+
Sparse matrix equations can be solved efficiently: they can be solved in linear time complexity, as
47+
opposed to the cubic complexity of naive Gaussian elimination. As a result, a sparse matrix solver
48+
is key to the performance of the power grid model. QR decomposition therefore is not a good
49+
candidate.
50+
51+
#### Pivot operations
52+
53+
Pivoting of blocks is expensive, both computationally and memory-wise, as it interferes with the
54+
sparse block structure of the matrix equations. To this end, a pre-fixed permutation can be chosen
55+
to avoid bock pivoting at a later stage.
56+
57+
The [topological structure](#topological-structure) of the grid does not change during the
58+
solving phase, so the permutation can be obtained by the minimum degree algorithm from just the
59+
topology alone, at the cost of potential [ill-conditioned pivot elements](#pivot-perturbation).
60+
61+
### Power system equation properties
62+
63+
[Power flow equations](../../user_manual/calculations.md#power-flow-algorithms) are not Hermitian
64+
and also not positive (semi-)definite. As a result, methods that depend on these properties cannot
65+
be used.
66+
67+
[State estimation equations](../../user_manual/calculations.md#state-estimation-algorithms) are
68+
intrinsically positive definite and Hermitian, but for
69+
[performance reasons](#performance-considerations), the matrix equation is augmented to achieve
70+
a consistent structure across the entire topology using Lagrange multipliers.
71+
72+
### Block-sparsity considerations
73+
74+
The power flow and state estimation equations involve block-sparse matrices: dense blocks, with a
75+
dimensionality varying between different calculation types, methods and symmetries, are distributed
76+
across the matrix in an extremely sparse way. The sparse structure can be pre-calculated, but the
77+
dense blocks need to be inverted separately. To make matters worse, the dense blocks may differ
78+
heavily in structure and contents between different nodes, and are often not solvable without
79+
pivoting.
80+
81+
### Custom sparse LU solver
82+
83+
The choice for a custom LU solver implementation comes from a number of considerations:
84+
85+
* LU-decomposition is the best choice, because QR-decomposition and Cholesky decomposition cannot
86+
solve the power system equations efficiently as a consequence of the properties
87+
* Alternative LU solver implementations are optimized for a variety of use cases that are less
88+
sparse than the ones encountered in power systems.
89+
* Alternative LU solver implementations do not have good block-sparse matrix equation solvers.
90+
91+
## Implementation
92+
93+
The LU solver implemented in the power grid model consists of 3 components:
94+
95+
* A sparse LU solver that:
96+
* handles factorization using the topological structure up to block-level
97+
* solves the sparse matrix equation given the factorization
98+
* A dense LU factor that handles individual blocks within the matrix equation
99+
100+
### Pivot perturbation
101+
102+
The LU solver implemented in the power grid model has support for pivot perturbation. The methods
103+
are described in [Li99](https://portal.nersc.gov/project/sparse/superlu/siam_pp99.pdf) and
104+
[Schenk04](http://ftp.gwdg.de/pub/misc/EMIS/journals/ETNA/vol.23.2006/pp158-179.dir/pp158-179.pdf).
105+
Pivot perturbation consists of selecting a pivot element. If its magnitude is too small compared
106+
to that of the other elements in the matrix, then it cannot be used in its current form. Selecting
107+
another pivot element is not desirable, as described in the section on
108+
[pivot operations](#pivot-operations), so the matrix is ill-conditioned.
109+
110+
Instead, a small perturbation is done on the pivot element. This makes the matrix equation solvable
111+
without selecting a different pivot element, at the cost of propating rounding errors.
112+
slightly different matrix that is then iteratively refined.
113+
114+
#### Pivot perturbation algorithm
115+
116+
\begin{align*}
117+
A = B && C = D \\
118+
&& E = F
119+
\end{align*}
120+
<!-- if (|pivot_element| < perturbation_threshold) then
121+
pivot_element = perturbation_threshold
122+
endif -->
123+
124+
### Dense LU factorization
125+
126+
The power grid model uses a modified version of the
127+
[`LUFullPiv` defined in Eigen](https://gitlab.com/libeigen/eigen/-/blob/3.4/Eigen/src/LU/FullPivLU.h)
128+
(credits go to the original author). The modification adds opt-in support for
129+
[pivot perturbation](#pivot-perturbation).
130+
131+
1. Set the remaining square matrix
132+
2. Find largest element in the remaining matrix by magnitude. This is the pivot element.
133+
3. If the magnitude of the pivot element is too small:
134+
1. If pivot perturbation is enabled, apply [pivot perturbation](#pivot-perturbation).
135+
2. Otherwise, if the matrix is exactly singular (pivot element is identically $0$) is disabled,
136+
raise a `SparseMatrixError`.

docs/advanced_documentation/build-guide.md

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ repository there are three builds:
1111

1212
* A `power-grid-model` [pip](https://pypi.org/project/power-grid-model/) Python package with C++ extension as the calculation core.
1313
* A [CMake](https://cmake.org/) project consisting of the C++ header-only calculation core, and the following build targets:
14-
* A dynamic library (`.dll` or `.so`) with stable pure C API/ABI which can be used by any application (enabled by default)
15-
* An install target that installs the package containing the dynamic library (enabled by default)
16-
* Native C++ unit tests
17-
* C API tests
18-
* A performance benchmark program
19-
* An example C program to call the shared library
14+
* A dynamic library (`.dll` or `.so`) with stable pure C API/ABI which can be used by any application (enabled by default)
15+
* An install target that installs the package containing the dynamic library (enabled by default)
16+
* Native C++ unit tests
17+
* C API tests
18+
* A performance benchmark program
19+
* An example C program to call the shared library
2020
* A separate example [CMake](https://cmake.org/) project with a small C++ program that shows how to find and use the installable
2121
package.
2222

@@ -39,7 +39,7 @@ minimum.
3939

4040
You need a C++ compiler with C++20 support. Below is a list of tested compilers:
4141

42-
**Linux**
42+
#### Linux
4343

4444
* gcc >= 11.0
4545
* Version 12.x tested using the version in the `manylinux_2_28` container.
@@ -51,14 +51,14 @@ You need a C++ compiler with C++20 support. Below is a list of tested compilers:
5151

5252
You can define the environment variable `CXX` to for example `clang++` to specify the C++ compiler.
5353

54-
**Windows**
54+
#### Windows
5555

5656
* MSVC >= 17.5
5757
* Latest release tested in CI (e.g. Visual Studio 2022, IDE or build tools)
5858
* Clang CL >= 15.0
5959
* Latest release tested in CI (e.g. Visual Studio 2022, IDE or build tools)
6060

61-
**macOS**
61+
#### macOS
6262

6363
* Clang >= 14.0.3
6464
* Latest release tested in CI
@@ -96,8 +96,8 @@ The table below shows the Python dependencies
9696

9797
## Build Python Package
9898

99-
Once you have prepared the build dependencies,
100-
you can install the library from source in editable mode with the development dependency.
99+
Once you have prepared the build dependencies,
100+
you can install the library from source in editable mode with the development dependency.
101101
Go to the root folder of the repository.
102102

103103
```shell
@@ -148,13 +148,12 @@ cmake --install build/ --config Release --prefix install/
148148
./install/bin/power_grid_model_package_test
149149
```
150150

151-
152151
### Developer build
153152

154-
If you opt for a developer build of Power Grid Model,
155-
you can use the pre-defined CMake presets to enable developer build, including all the tests, warnings, examples, and benchmark. In the presets the [Ninja](https://ninja-build.org/) generator is used.
153+
If you opt for a developer build of Power Grid Model,
154+
you can use the pre-defined CMake presets to enable developer build, including all the tests, warnings, examples, and benchmark. In the presets the [Ninja](https://ninja-build.org/) generator is used.
156155
In principle, you can use any C++ IDE with cmake and ninja support to develop the C++ project.
157-
It is also possible to use the bare CMake CLI to set up the project.
156+
It is also possible to use the bare CMake CLI to set up the project.
158157
Supported presets for your development platform can be listed using `cmake --list-presets`.
159158

160159
In the developer build the following build targets (directories) are enabled:
@@ -166,14 +165,13 @@ In the developer build the following build targets (directories) are enabled:
166165
* `tests/benchmark_cpp`: the C++ benchmark target for performance measure.
167166
* `power_grid_model_c_example`: an example C program to call the dynamic library
168167

169-
170168
On Linux/macOS, the presets will use command `clang`/`clang++` or `gcc`/`g++` to find the relevant `clang` or `gcc` compiler. It is the developer's reponsiblity to properly define symbolic links (which should be discoverable through `PATH` environment variable) of `clang` or `gcc` compiler in your system. If you want to build with `clang-tidy`, you also need to define symbolic link of `clang-tidy` to point to the actual `clang-tidy` executable of your system.
171169

172170
Similar also applies to Windows: the presets will use command `cl.exe` or `clang-cl.exe` to find the compiler. Developer needs to make sure the they are discoverable in `PATH`. For x64 Windows native development using MSVC or Clang CL, please use the `x64 Native Command Prompt`, which uses `vcvarsall.bat` to set up the appropriate build environment.
173171

174172
## Visual Studio Code Support
175173

176-
You can use any IDE to develop this project. As a popular cross-platform IDE, the settings for Visual Studio Code is preconfigured in the folder `.vscode`. You can open the repository folder with VSCode and the configuration will be loaded automatically.
174+
You can use any IDE to develop this project. As a popular cross-platform IDE, the settings for Visual Studio Code is preconfigured in the folder `.vscode`. You can open the repository folder with VSCode and the configuration will be loaded automatically.
177175

178176
```{note}
179177
VSCode (as well as some other IDEs) does not set its own build environment itself. For optimal usage, open the folder
@@ -238,8 +236,8 @@ brew install boost eigen nlohmann-json msgpack-cxx doctest cmake
238236
239237
### Build Python Library from Source
240238
241-
It is recommended to create a virtual environment.
242-
Clone repository, create and activate virtual environment.
239+
It is recommended to create a virtual environment.
240+
Clone repository, create and activate virtual environment.
243241
Go to a root folder you prefer to save the repositories.
244242
245243
```shell
@@ -288,7 +286,6 @@ or install using
288286
cmake --build --preset <preset> --target install
289287
```
290288
291-
292289
## Example Setup for Windows 10
293290
294291
Define the following environment variable user-wide:
@@ -302,10 +299,10 @@ Define the following environment variable user-wide:
302299
You need to install the MSVC compiler. You can either install the whole Visual Studio IDE or just the build tools.
303300
304301
* [Visual Studio Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe) (free)
305-
* Select C++ build tools
302+
* Select C++ build tools
306303
* Full [Visual Studio](https://visualstudio.microsoft.com/vs/) (All three versions are suitable. Check the license!)
307-
* Select Desktop Development with C++
308-
* [Optional] Select `C++ Clang tools for Windows`
304+
* Select Desktop Development with C++
305+
* [Optional] Select `C++ Clang tools for Windows`
309306
310307
Other toolchains:
311308
@@ -331,8 +328,8 @@ conda create --yes -p C:\conda_envs\cpp_pkgs -c conda-forge libboost-headers eig
331328
332329
### Build Python Library from Source
333330
334-
It is recommended to create a `conda` environment.
335-
Clone repository, create and activate `conda` environment.
331+
It is recommended to create a `conda` environment.
332+
Clone repository, create and activate `conda` environment.
336333
Go to a root folder you prefer to save the repositories, open a Git Bash Console.
337334
338335
```shell

docs/advanced_documentation/python-wrapper-design.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Only classes that have connections to other classes are shown in this diagram.
1818

1919
```{raw} html
2020
<div style="overflow-x: auto; white-space: nowrap;">
21-
<img src="../_static/classes.svg" style="max-width: none;" alt="Classe diagram">
21+
<img src="../_static/classes.svg" style="max-width: none;" alt="Class diagram">
2222
</div>.
2323
```
2424

@@ -27,11 +27,11 @@ Only classes that have connections to other classes are shown in this diagram.
2727
This is the package diagram of the `power_grid_model` package.
2828

2929
```{note}
30-
Only modules that import (or are impored by) other modules are shown in this diagram.
30+
Only modules that import (or are imported by) other modules are shown in this diagram.
3131
```
3232

3333
```{raw} html
3434
<div style="overflow-x: auto; white-space: nowrap;">
3535
<img src="../_static/packages.svg" style="max-width: none;" alt="Package diagram">
3636
</div>.
37-
```
37+
```

0 commit comments

Comments
 (0)