11#include " MatrixCoeff.h"
2+ #include " MatrixWrapper.h"
23
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 ( )
56{
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+ }
726
27+ void MatrixCoeff::init (MatrixInterface* matrix)
28+ {
829 for (int i = 0 ; i < N; i++)
930 {
1031 int i_l = mesh->left_of (i);
1132 int i_r = mesh->right_of (i);
1233 int i_t = mesh->top_of (i);
1334 int i_b = mesh->bottom_of (i);
1435
15- A_m (i, i) = aP[i];
36+ matrix-> setNum (i, i, aP[i]) ;
1637
1738 if (!mesh->is_at_left_boundary (i))
1839 {
19- A_m (i, i_l) = -aL[i];
40+ matrix-> setNum (i, i_l, -aL[i]) ;
2041 }
2142 if (!mesh->is_at_right_boundary (i))
2243 {
23- A_m (i, i_r) = -aR[i];
44+ matrix-> setNum (i, i_r, -aR[i]) ;
2445 }
2546 if (!mesh->is_at_bottom_boundary (i))
2647 {
27- A_m (i, i_b) = -aB[i];
48+ matrix-> setNum (i, i_b, -aB[i]) ;
2849 }
2950 if (!mesh->is_at_top_boundary (i))
3051 {
31- A_m (i, i_t ) = -aT[i];
52+ matrix-> setNum (i, i_t , -aT[i]) ;
3253 }
3354 }
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;
4255}
4356
44- MatrixCoeff& MatrixCoeff::addConvectionTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
57+ MatrixCoeff& MatrixCoeff::addConvectionTerm ()
4558{
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 ;
5063
51- double q_w = boundary. q_w ;
64+ double q_w = boundary-> q_w ;
5265
5366 double Ax = mesh->get_Ax ();
5467 double Ay = mesh->get_Ay ();
@@ -59,8 +72,6 @@ MatrixCoeff& MatrixCoeff::addConvectionTerm(const Mesh* mesh, const Boundary& bo
5972 const VectorXd& F_b = mesh->get_F_b ();
6073 const VectorXd& F_t = mesh->get_F_t ();
6174
62- int N = mesh->get_N ();
63-
6475 aL += F_l.cwiseMax (VectorXd::Zero (N));
6576 aR += (-F_r).cwiseMax (VectorXd::Zero (N));
6677 aB += F_b.cwiseMax (VectorXd::Zero (N));
@@ -99,13 +110,13 @@ MatrixCoeff& MatrixCoeff::addConvectionTerm(const Mesh* mesh, const Boundary& bo
99110 return *this ;
100111}
101112
102- MatrixCoeff& MatrixCoeff::addDiffusionTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
113+ MatrixCoeff& MatrixCoeff::addDiffusionTerm ()
103114{
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 ;
109120
110121 double Ax = mesh->get_Ax ();
111122 double Ay = mesh->get_Ay ();
@@ -116,8 +127,6 @@ MatrixCoeff& MatrixCoeff::addDiffusionTerm(const Mesh* mesh, const Boundary& bou
116127 const VectorXd& DA_B = mesh->get_DA_B ();
117128 const VectorXd& DA_T = mesh->get_DA_T ();
118129
119- int N = mesh->get_N ();
120-
121130 aL += DA_L;
122131 aR += DA_R;
123132 aB += DA_B;
@@ -157,9 +166,9 @@ MatrixCoeff& MatrixCoeff::addDiffusionTerm(const Mesh* mesh, const Boundary& bou
157166 return *this ;
158167}
159168
160- MatrixCoeff& MatrixCoeff::addSourceTerm (const Mesh* mesh, const Boundary& boundary, const Source& source )
169+ MatrixCoeff& MatrixCoeff::addSourceTerm ()
161170{
162- double S_bar = source. S_bar ;
171+ double S_bar = source-> S_bar ;
163172
164173 const VectorXd& V = mesh->get_V ();
165174
@@ -168,4 +177,44 @@ MatrixCoeff& MatrixCoeff::addSourceTerm(const Mesh* mesh, const Boundary& bounda
168177 Su += S_bar * V;
169178
170179 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;
171220}
0 commit comments