1
1
#include " MatrixCoeff.h"
2
+ #include " MatrixWrapper.h"
2
3
3
- // a_{p} T_{p}=a_{L} T_{L}+a_{R} T_{R}+ S_{u}
4
- void MatrixCoeff::initMatrix ( const Mesh* mesh, const Boundary& boundary, const Source& source )
4
+ // a_p T_p = a_L T_L + a_R T_R + ... + S_{u}
5
+ void MatrixCoeff::initDenseMatrix ( )
5
6
{
6
- int N = mesh->get_N ();
7
+ init (&dense_matrix_wrapper);
8
+
9
+ b_m = Su;
10
+ }
11
+
12
+ void MatrixCoeff::initSparseMatrix ()
13
+ {
14
+ SparseMatrix<double > A_m = sparse_matrix_wrapper.getMatrix ();
15
+
16
+ // 每列预留5个元素的空间,用于插入
17
+ // ref. http://eigen.tuxfamily.org/dox/group__TutorialSparse.html - Filling a sparse matrix
18
+ A_m.reserve (VectorXi::Constant (N, 5 ));
19
+
20
+ init (&sparse_matrix_wrapper);
21
+
22
+ A_m.makeCompressed (); // optional
23
+
24
+ b_m = Su;
25
+ }
7
26
27
+ void MatrixCoeff::init (MatrixInterface* matrix)
28
+ {
8
29
for (int i = 0 ; i < N; i++)
9
30
{
10
31
int i_l = mesh->left_of (i);
11
32
int i_r = mesh->right_of (i);
12
33
int i_t = mesh->top_of (i);
13
34
int i_b = mesh->bottom_of (i);
14
35
15
- A_m (i, i) = aP[i];
36
+ matrix-> setNum (i, i, aP[i]) ;
16
37
17
38
if (!mesh->is_at_left_boundary (i))
18
39
{
19
- A_m (i, i_l) = -aL[i];
40
+ matrix-> setNum (i, i_l, -aL[i]) ;
20
41
}
21
42
if (!mesh->is_at_right_boundary (i))
22
43
{
23
- A_m (i, i_r) = -aR[i];
44
+ matrix-> setNum (i, i_r, -aR[i]) ;
24
45
}
25
46
if (!mesh->is_at_bottom_boundary (i))
26
47
{
27
- A_m (i, i_b) = -aB[i];
48
+ matrix-> setNum (i, i_b, -aB[i]) ;
28
49
}
29
50
if (!mesh->is_at_top_boundary (i))
30
51
{
31
- A_m (i, i_t ) = -aT[i];
52
+ matrix-> setNum (i, i_t , -aT[i]) ;
32
53
}
33
54
}
34
-
35
- b_m = Su;
36
-
37
- cout << " A_m: " << endl << A_m << endl;
38
- cout << endl;
39
-
40
- cout << " b_m: " << endl << b_m << endl;
41
- cout << endl;
42
55
}
43
56
44
- MatrixCoeff& MatrixCoeff::addConvectionTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
57
+ MatrixCoeff& MatrixCoeff::addConvectionTerm ()
45
58
{
46
- double T_l = boundary. T_left ;
47
- double T_r = boundary. T_right ;
48
- double T_b = boundary. T_bottom ;
49
- double T_t = boundary. T_top ;
59
+ double T_l = boundary-> T_left ;
60
+ double T_r = boundary-> T_right ;
61
+ double T_b = boundary-> T_bottom ;
62
+ double T_t = boundary-> T_top ;
50
63
51
- double q_w = boundary. q_w ;
64
+ double q_w = boundary-> q_w ;
52
65
53
66
double Ax = mesh->get_Ax ();
54
67
double Ay = mesh->get_Ay ();
@@ -59,8 +72,6 @@ MatrixCoeff& MatrixCoeff::addConvectionTerm(const Mesh* mesh, const Boundary& bo
59
72
const VectorXd& F_b = mesh->get_F_b ();
60
73
const VectorXd& F_t = mesh->get_F_t ();
61
74
62
- int N = mesh->get_N ();
63
-
64
75
aL += F_l.cwiseMax (VectorXd::Zero (N));
65
76
aR += (-F_r).cwiseMax (VectorXd::Zero (N));
66
77
aB += F_b.cwiseMax (VectorXd::Zero (N));
@@ -99,13 +110,13 @@ MatrixCoeff& MatrixCoeff::addConvectionTerm(const Mesh* mesh, const Boundary& bo
99
110
return *this ;
100
111
}
101
112
102
- MatrixCoeff& MatrixCoeff::addDiffusionTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
113
+ MatrixCoeff& MatrixCoeff::addDiffusionTerm ()
103
114
{
104
- double T_l = boundary. T_left ;
105
- double T_r = boundary. T_right ;
106
- double T_b = boundary. T_bottom ;
107
- double T_t = boundary. T_top ;
108
- double q_w = boundary. q_w ;
115
+ double T_l = boundary-> T_left ;
116
+ double T_r = boundary-> T_right ;
117
+ double T_b = boundary-> T_bottom ;
118
+ double T_t = boundary-> T_top ;
119
+ double q_w = boundary-> q_w ;
109
120
110
121
double Ax = mesh->get_Ax ();
111
122
double Ay = mesh->get_Ay ();
@@ -116,8 +127,6 @@ MatrixCoeff& MatrixCoeff::addDiffusionTerm(const Mesh* mesh, const Boundary& bou
116
127
const VectorXd& DA_B = mesh->get_DA_B ();
117
128
const VectorXd& DA_T = mesh->get_DA_T ();
118
129
119
- int N = mesh->get_N ();
120
-
121
130
aL += DA_L;
122
131
aR += DA_R;
123
132
aB += DA_B;
@@ -157,9 +166,9 @@ MatrixCoeff& MatrixCoeff::addDiffusionTerm(const Mesh* mesh, const Boundary& bou
157
166
return *this ;
158
167
}
159
168
160
- MatrixCoeff& MatrixCoeff::addSourceTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
169
+ MatrixCoeff& MatrixCoeff::addSourceTerm ()
161
170
{
162
- double S_bar = source. S_bar ;
171
+ double S_bar = source-> S_bar ;
163
172
164
173
const VectorXd& V = mesh->get_V ();
165
174
@@ -168,4 +177,44 @@ MatrixCoeff& MatrixCoeff::addSourceTerm(const Mesh* mesh, const Boundary& bounda
168
177
Su += S_bar * V;
169
178
170
179
return *this ;
180
+ }
181
+
182
+ void MatrixCoeff::DebugSolve ()
183
+ {
184
+ initDenseMatrix ();
185
+
186
+ MatrixXd& A_m = dense_matrix_wrapper.getMatrix ();
187
+
188
+ // 求解矩阵
189
+ x = A_m.fullPivLu ().solve (b_m);
190
+
191
+ // 输出结果
192
+ cout << " A_m: " << endl << A_m << endl;
193
+ cout << endl;
194
+
195
+ cout << " b_m: " << endl << b_m << endl;
196
+ cout << endl;
197
+
198
+ cout << " Solution: " << endl << x << endl;
199
+ }
200
+
201
+ void MatrixCoeff::Solve ()
202
+ {
203
+ initSparseMatrix ();
204
+
205
+ SparseMatrix<double >& A_m = sparse_matrix_wrapper.getMatrix ();
206
+
207
+ // ref. http://eigen.tuxfamily.org/dox/classEigen_1_1BiCGSTAB.html
208
+ // ref. http://eigen.tuxfamily.org/dox/group__TopicSparseSystems.html#TutorialSparseSolverConcept
209
+ // ref. http://eigen.tuxfamily.org/dox/group__MatrixfreeSolverExample.html
210
+
211
+ // BiCGSTAB<SparseMatrix<double>, Eigen::IdentityPreconditioner> solver;
212
+ BiCGSTAB<SparseMatrix<double >, Eigen::IncompleteLUT<double >> solver;
213
+ solver.compute (A_m);
214
+ x = solver.solve (b_m);
215
+
216
+ std::cout << " #iterations: " << solver.iterations () << std::endl;
217
+ std::cout << " estimated error: " << solver.error () << std::endl;
218
+
219
+ std::cout << " x: " << std::endl << x << std::endl;
171
220
}
0 commit comments