Flow123d  JS_before_hm-1601-gc6ac32d
local_system.hh
Go to the documentation of this file.
1 
2 #ifndef LOCAL_SYSTEM_HH_
3 #define LOCAL_SYSTEM_HH_
4 
5 #include <armadillo>
6 #include "system/index_types.hh"
7 
8 class LinSys;
9 
10 /** Local system class is meant to be used for local assembly and then pass to global linear system.
11  * The key idea is to take care of known solution values (Dirichlet boundary conditions) in a common way.
12  *
13  * A] Usage of the class consists of 5 steps:
14  * 1) create local system, set local/global DoFs.
15  * 2) possibly setup sparsity pattern for the local system
16  * 3) set matrix and RHS entries
17  * 4) set all known values (Dirichlet BC)
18  * (the order of items 3 and 4 does not matter)
19  * 5) possibly eliminate the known solution
20  * (possibly fix the diagonal entries of the local system, where Dirichlet BC is set)
21  * 6) pass the local system to the global system, possibly with the map local_to_global
22  *
23  * B] Scenario with computation of Schur complement:
24  * 1) do A1, do not have to set dof indices (if not doing B3)
25  * 2) do A2, A3
26  * 3) possibly do A4, A5, if there is known solution for the dofs not included in the Schur complement
27  * 3) create another LocalSystem for Schur complement (local_schur), possibly set dof indices
28  * 4) possibly do A2 on local_schur
29  * 4) compute Schur complement, passing the prepared local_schur
30  * 5) if not done before, set dof indices
31  * 6) possibly do A4, A5 on local_schur
32  * 7) do A6 with local_schur
33  *
34  * C] Reconstruction from the Schur complement
35  * 1) do A1, A3
36  * 2) reconstruct the full solution
37  *
38  * TODO:
39  * - set dofs as references
40  * - done: use arma::vec<int> to keep dofs (efficient, can be constructed from raw arrays)
41  * - done: use local dof indeces to set solution
42  * - rename set_solution to set_constraint
43  * -
44  */
46 {
47 public:
48  /**
49  * Global row and col indices. Are public and can be freely set.
50  * Nevertheless one can also provide reference to already existing arrays through
51  * specific constructor or reset function.
52  */
54 
55  /**
56  * @brief Default constructor.
57  *
58  * Object must be initialized by subsequent call of reset(nrows, ncols).
59  */
60  LocalSystem();
61 
62  /** @brief Constructor.
63  *
64  * @p nrows is number of rows of local system
65  * @p ncols is number of columns of local system
66  */
67  LocalSystem(uint nrows, uint ncols);
68 
69  /// Resets the matrix, RHS, dofs to zero and clears solution settings
70  void reset();
71 
72  /// Resize and reset.
73  void reset(uint nrows, uint ncols);
74 
75  /**
76  * Resize and reset. Set dofs vectors to reuse arrays provided by given vectors.
77  * Given vectors can not be changed until next call to of any reset function.
78  */
79  void reset(const LocDofVec &row_dofs, const LocDofVec &col_dofs);
80 
81  const arma::mat& get_matrix() {return matrix;}
82  const arma::vec& get_rhs() {return rhs;}
83 
84  /** @brief Set the position and value of known solution. E.g. Dirichlet boundary condition.
85  *
86  * @p loc_dofs is local row index in solution vector
87  * @p solution is the values of the solution
88  * @p diag_val is preferred diagonal value on the solution row
89  */
90  void set_solution(uint loc_dof, double solution, double diag=0.0);
91 
92  void set_solution_row(uint loc_row, double solution, double diag=0.0);
93 
94  void set_solution_col(uint loc_col, double solution);
95 
96 
97  /**
98  * When finished with assembly of the local system,
99  * this function eliminates all the known dofs.
100  *
101  * It is skipped if there is not any solution dof set.
102  *
103  * During elimination, the (global) diagonal entries on the rows, where the solution is set, might be zero.
104  * Therefore it is necessary to set a proper value to the diagonal entry
105  * and respective RHS entry, such that the given solution holds.
106  * If preferred diagonal value has been set by @p set_solution then it is used.
107  *
108  * Calling this function after the assembly of local system
109  * and before passing the local system to the global one
110  * is finished is users's responsibility.
111  */
112  void eliminate_solution();
113 
114  /** @brief Adds a single entry into the local system.
115  *
116  * @p row is local row index of local system
117  * @p col is local column index of local system
118  * @p mat_val is matrix entry value
119  * @p rhs_val is RHS entry value
120  */
121  void add_value(uint row, uint col,
122  double mat_val, double rhs_val);
123 
124  /** @brief Matrix entry.
125  * Adds a single entry into the local system matrix.
126  *
127  * @p row is local row index of local system
128  * @p col is local column index of local system
129  * @p mat_val is matrix entry value
130  */
131  void add_value(uint row, uint col,
132  double mat_val);
133 
134  /** @brief RHS entry.
135  * Adds a single entry into the local system RHS.
136  *
137  * @p row is local row index of local system
138  * @p rhs_val is RHS entry value
139  */
140  void add_value(uint row, double rhs_val);
141 
143  void set_rhs(arma::vec rhs);
144 
145  /// Sets the sparsity pattern for the local system.
146  /** Due to petsc options: MatSetOption(matrix_, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE)
147  * all zeros will be thrown away from the system.
148  * If we do not want some zero entries in the system matrix to be thrown away,
149  * we can set these entries with this almost zero value.
150  *
151  * Almost_zero values will be set in all entries: sp(i,j) != 0
152  */
153  void set_sparsity(const arma::umat & sp);
154 
155  /** @brief Computes Schur complement of the local system: S = C - B * invA * Bt
156  * Applicable for square matrices.
157  * It can be called either after eliminating Dirichlet dofs,
158  * or the Dirichlet dofs can be set on the Schur complement
159  * and the elimination done on the Schur complement.
160  *
161  * @p offset index of the first row/column of submatrix C (size of A)
162  * @p schur (output) LocalSystem with Schur complement
163  * @p negative if true, the schur complement (including its rhs) is multiplied by -1.0
164  */
165  void compute_schur_complement(uint offset, LocalSystem& schur, bool negative=false) const;
166 
167  /** @brief Reconstructs the solution from the Schur complement solution: x = invA*b - invA * Bt * schur_solution
168  * Applicable for square matrices.
169  *
170  * @p offset index of the first row/column of submatrix C (size of A)
171  * @p schur_solution solution of the Schur complement
172  * @p reconstructed_solution (output) reconstructed solution of the complementary variable
173  */
174  void reconstruct_solution_schur(uint offset, const arma::vec &schur_solution, arma::vec& reconstructed_solution) const;
175 
176 protected:
177  void set_size(uint nrows, uint ncols);
178 
179  arma::mat matrix; ///< local system matrix
180  arma::vec rhs; ///< local system RHS
181 
182  arma::mat sparsity; ///< sparsity pattern
183 
184  /// Number of rows/cols to be eliminated due to known solution.
186  LocDofVec elim_rows; /// Rows indices of rows to be eliminated.
187  LocDofVec elim_cols; /// Cols indices of cols to be eliminated.
188  arma::vec solution_rows; /// Values of the known solution (for row dofs).
189  arma::vec solution_cols; /// Values of the known solution (for col dofs).
190  arma::vec diag_rows; /// Prefered values on the diagonal after elimination.
191 
192  /// Due to petsc options: MatSetOption(matrix_, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE)
193  /// all zeros will be thrown away from the system.
194  /// If we do not want some zero entries in the system matrix to be thrown away,
195  /// we can set these entries with this almost zero value.
196  ///
197  /// This is done for example when BC values are eliminated and later the BC changes to different type (e.g. seepage).
198  /// Another case is keeping the structure of matrix unchanged for the schur complements -
199  /// for that we fill the whole diagonal (escpecially block C in darcy flow) with artificial zeros.
200  static constexpr double almost_zero = std::numeric_limits<double>::min();
201 
202 
203  friend class LinSys;
204 };
205 
206 #endif // LOCAL_SYSTEM_HH_
LocDofVec row_dofs
Definition: local_system.hh:53
void set_solution_col(uint loc_col, double solution)
Definition: local_system.cc:96
const arma::mat & get_matrix()
Definition: local_system.hh:81
const arma::vec & get_rhs()
Definition: local_system.hh:82
ArmaVec< double, N > vec
Definition: armor.hh:885
arma::Col< IntIdx > LocDofVec
Definition: index_types.hh:28
unsigned int uint
void set_matrix(arma::mat matrix)
void compute_schur_complement(uint offset, LocalSystem &schur, bool negative=false) const
Computes Schur complement of the local system: S = C - B * invA * Bt Applicable for square matrices...
void set_sparsity(const arma::umat &sp)
Sets the sparsity pattern for the local system.
LocDofVec elim_rows
static constexpr double almost_zero
Prefered values on the diagonal after elimination.
LocDofVec elim_cols
Rows indices of rows to be eliminated.
arma::vec rhs
local system RHS
arma::vec solution_rows
Cols indices of cols to be eliminated.
void add_value(uint row, uint col, double mat_val, double rhs_val)
Adds a single entry into the local system.
LocDofVec col_dofs
Definition: local_system.hh:53
ArmaMat< double, N, M > mat
Definition: armor.hh:888
arma::mat sparsity
sparsity pattern
void reset()
Resets the matrix, RHS, dofs to zero and clears solution settings.
Definition: local_system.cc:45
void set_size(uint nrows, uint ncols)
Definition: local_system.cc:28
arma::vec diag_rows
Values of the known solution (for col dofs).
LocalSystem()
Default constructor.
Definition: local_system.cc:9
arma::mat matrix
local system matrix
void reconstruct_solution_schur(uint offset, const arma::vec &schur_solution, arma::vec &reconstructed_solution) const
Reconstructs the solution from the Schur complement solution: x = invA*b - invA * Bt * schur_solution...
void set_solution_row(uint loc_row, double solution, double diag=0.0)
Definition: local_system.cc:89
void set_rhs(arma::vec rhs)
arma::vec solution_cols
Values of the known solution (for row dofs).
uint n_elim_rows
Number of rows/cols to be eliminated due to known solution.
void eliminate_solution()
void set_solution(uint loc_dof, double solution, double diag=0.0)
Set the position and value of known solution. E.g. Dirichlet boundary condition.
Definition: local_system.cc:81