You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Providing the Jacobian matrix for the DAE solver is optional. If not provided by the user, the Jacobian matrix will be computed by the solver automatically, using algorithmic differentiation package [`autodiff`](https://autodiff.github.io/).
18
+
However, for big DAE systems, it is highly recommended to provide manually (analytically) derived Jacobian. This can save a lot of computation time for the solver and significantly speed it up.
19
+
20
+
## Jacobian matrix definition
21
+
22
+
The main Jacobian matrix class `daecpp::JacobianMatrix` is an abstract class that provides an interface to define the Jacobian matrix $$\mathbf{J}(\mathbf{x}, t)$$.
23
+
In order to make use of this class, the user should inherit it and overload the `()` operator:
In the code above, the Jacobian matrix `J` should be defined in the [three-array sparse format](sparse-matrix.html) and can depend on the current state vector $$\mathbf{x}$$ and time `t`.
37
+
Initially, matrix `J` is empty and should be filled with non-zero elements.
38
+
39
+
{: .note }
40
+
The type of vector `x` in the class definition above is `daecpp::state_vector`, which is an alias of `std::vector<float_type>` type. See [`dae-cpp` types](https://dae-cpp.github.io/prerequisites.html#dae-cpp-types) section for more information.
41
+
42
+
## Examples
43
+
44
+
Consider the following vector function $$\mathbf{f}(\mathbf{x}, t)$$ from the [Vector Function class](vector-function.html#examples) section:
45
+
46
+
$$
47
+
\mathbf{f}(\mathbf{x}, t) =
48
+
\begin{vmatrix}
49
+
z + 1 \\
50
+
x^2 + y \\
51
+
2t
52
+
\end{vmatrix}.
53
+
$$
54
+
55
+
Differentiation this vector w.r.t. $$\{x,y,z\}$$ gives us the following Jacobian matrix $$\mathbf{J}$$:
56
+
57
+
$$
58
+
\mathbf{J} =
59
+
\begin{vmatrix}
60
+
0 & 0 & 1 \\
61
+
2x & 1 & 0 \\
62
+
0 & 0 & 0
63
+
\end{vmatrix}.
64
+
$$
65
+
66
+
It has 3 non-zero elements and does not depend on time.
67
+
In the code, this Jacobian matrix can be defined as
Inhereting the `daecpp::JacobianMatrix` class is a good practice (it serves as a blueprint), however, the user is allowed to define Jacobian matrices using their own custom classes, for example:
It is recommended to pre-allocate memory for the Jacobian matrix using `reserve(N_elements)` method, where `N_elements` is the number of non-zero elements in the matrix. If the number of non-zeros is difficult to estimate, it is better to overestimate `N_elements` than underestimate it to avoid unnecessary copying and memory reallocations.
100
+
101
+
For more information about defining the matrix in sparse format, refer to the [Sparse Matrix class](sparse-matrix.html) section.
102
+
103
+
## Automatic Jacobian matrix
104
+
105
+
The solver provides a helper class `daecpp::JacobianAutomatic` to compute the Jacobian matrix for the given vector function $$\mathbf{f}(\mathbf{x}, t)$$ algorithmically using [`autodiff`](https://autodiff.github.io/) package.
106
+
For relatively small systems, the user does not even need to define the Jacobian, not even automatic one. This will be handled by the solver itself. Behind the scenes, the solver will create an automatic Jacobian matrix object for the user, if analytic Jacobian is not provided.
107
+
108
+
However, in some cases, it can be difficult to derive the Jacobian matrix analytically. Or if the user has provided the Jacobian matrix, but the solution diverges, which means there might be a bug in the Jacobian matrix definition. In these cases, the user can try to feed the automatic Jacobian matrix to the solver explicitly, or print out (or save to a file) both user-defined and automatic Jacobians for comparison to find possible errors in the matrix definition.
109
+
110
+
In order to construct an automatic Jacobian matrix object, the user needs to provide the vector function object `rhs` (see [Vector Function class](vector-function.html) section):
111
+
112
+
```cpp
113
+
// Creates automatic Jacobian object for the given user-defined RHS
114
+
daecpp::JacobianAutomatic automaticJacobian(rhs);
115
+
```
116
+
117
+
In the example above, we created an object `automaticJacobian` which computes automatic Jacobian in sparse format suitable for the solver.
118
+
To print the Jacobian out (for example, to compare with the user-defined analytic Jacobian), convert the matrix to dense format and use `std::cout`:
119
+
120
+
```cpp
121
+
daecpp::sparse_matrix J; // Empty Jacobian matrix
122
+
daecpp::state_vector x(N, 1.0); // State vector of size `N` populated with `1.0`
123
+
double t = 1.0; // Time
124
+
125
+
// Computes automatic Jacobian for the given state `x` and time `t`
126
+
automaticJacobian(J, x, t);
13
127
14
-
## Subtitle
128
+
// Prints out Jacobian in dense format
129
+
std::cout << J.dense(N) << '\n';
130
+
```
15
131
16
-
Text
132
+
{: .highlight }
133
+
User-defined vs analytic Jacobian comparison functionality (element by element) will be added in future versions of the solver.
Copy file name to clipboardExpand all lines: docs/mass-matrix.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ Initially, matrix `M` is empty and should be filled with non-zero elements.
33
33
34
34
## Examples
35
35
36
-
Consider the following mass matrix $$\mathbf{x}$$:
36
+
Consider the following mass matrix $$\mathbf{M}$$:
37
37
38
38
$$
39
39
\mathbf{M} =
@@ -76,7 +76,7 @@ struct UserDefinedMassMatrix
76
76
{: .note }
77
77
It is recommended to pre-allocate memory for the mass matrix using `reserve(N_elements)` method, where `N_elements` is the number of non-zero elements in the matrix. If the number of non-zeros is difficult to estimate, it is better to overestimate `N_elements` than underestimate it to avoid unnecessary copying and memory reallocations.
78
78
79
-
For more information about defining the matrix in sparse format, refer to the [Sparse Matrix](sparse-matrix.html) section.
79
+
For more information about defining the matrix in sparse format, refer to the [Sparse Matrix class](sparse-matrix.html) section.
Copy file name to clipboardExpand all lines: docs/vector-function.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ Vector `f` is already pre-allocated with `f.size() == x.size()` and should be us
33
33
The elements of vectors `x` and `f` can be accessed using square brackets `[]`.
34
34
35
35
{: .note }
36
-
The type of vectors `f` and `x` is `daecpp::state_type`, which is an [`autodiff`](https://autodiff.github.io/)'s type used to perform automatic (algorithmic) differentiation of the vector function `f`. See [`dae-cpp` types](https://dae-cpp.github.io/prerequisites.html#dae-cpp-types) section.
36
+
The type of vectors `f` and `x` is `daecpp::state_type`, which is an alias of [`autodiff`](https://autodiff.github.io/)'s type used to perform automatic (algorithmic) differentiation of the vector function `f`. See [`dae-cpp` types](https://dae-cpp.github.io/prerequisites.html#dae-cpp-types) section.
0 commit comments