問題:-/Delta u = f u |_{/partial /Omega} = u_b
***** $ls
CVS D.d Makefile possion_equation.cfg possion_equation.cpp possion_equation.net README run
------------------------------------------------------------------------------------
***** README (運行步驟)
This example will solve a Possion equation on an easymesh generated data.
The obtained solution is saved in file "u.dx".
Usage:
1. compile with make [-e debug=no];
2. generate the mesh with easymesh as:
easymesh D
3. run with ./run;
4. view the obtained numerical solution with OpenDX;
The obtained solution is saved in file "u.dx".
Usage:
1. compile with make [-e debug=no];
2. generate the mesh with easymesh as:
easymesh D
3. run with ./run;
4. view the obtained numerical solution with OpenDX;
[補充]
3. 本目錄的例子只需運行 $ ./run 或者 $ ./main
(後者需要先設置環境變量 $ export AFEPACK_TEMPLATE_PATH=/usr/local/AFEPack/template/triangle,否則找不到讀入文件的路徑)
4. OpenDX ——> Edit Visual Programs...——> 選 possion_equation.net
(possion_equation.cfg 是OpenDx用到的配置文件)
雙擊FileSelector,(若需要)修改輸出的數值解位置,保存
Execute ——> 選Execute Once
***** Makefile(略)
***** possion_equation.cpp(略)
可用 $ cat -n possion_equation.cpp 加上行號顯示
***** D.d(EasyMesh輸入文件,略)
***** run(shell腳本)
#! /bin/sh
export AFEPACK_PATH="/usr/local/AFEPack"
export AFEPACK_TEMPLATE_PATH="$AFEPACK_PATH/template/triangle"
exec ./main $*
export AFEPACK_PATH="/usr/local/AFEPack"
export AFEPACK_TEMPLATE_PATH="$AFEPACK_PATH/template/triangle"
exec ./main $*
[補充](shell編程和環境變量,略)
$*:執行shell程序時,傳遞給程序的所有參數組成的一個字符串。
比如:
$ ./run D 實際是運行了 ./main D
$ ./run parameters are three
此時 $* = parameters are three;$1 = parameters;$2 = are; $3 = three; $# = 3.
------------------------------------------------------------------------------------
***** 關於possion_equation.cpp的補充解釋(詳見[筆記2.2])
(1) Vector類(實現數值的 STL:vector)
65 Vector<double> right_hand_side;
template<typename number> class Vector;
位置:/usr/local/deal.II/lac/include/lac/vector.h 和 vector.templates.h
(2) 求解方程
73 AMGSolver solver(stiff_matrix);
74 solver.solve(solution, right_hand_side);
74 solver.solve(solution, right_hand_side);
[運行提示信息] 其中 failed to converge...,無大礙,唯不順眼也
AMGSolver initializing ... OK! grid levels: 3
AMGSolver begin with initial residual 0.458239 ...
failed to converge with residual 9.01090e-11 at step 21.
L2 error = 0.000629244
[原因] AMGSolver::solve是默認參數的函數,可將20放大,比如:
74行改爲:solver.solve(solution, right_hand_side, 0, 0, 50);
class AMGSolver {
...
public:
void solve(Vector<double>& x,
const Vector<double>& r,
double tol = 0.0,
unsigned int s = 0,
unsigned int s1 = 20) const;
...
};
...
public:
void solve(Vector<double>& x,
const Vector<double>& r,
double tol = 0.0,
unsigned int s = 0,
unsigned int s1 = 20) const;
...
};
x the solution vector
r the right hand side vector
tol tolerence
s 0: solve mode; 1: precondition mode
s1 upper bound of iteration step
AMGSolver::solve 函數定義在:/usr/local/AFEPack/library/src/AMGSolver.cpp
[修改後結果]
73 AMGSolver solver(stiff_matrix);
74 solver.solve(solution, right_hand_side,0,0,50);
AMGSolver initializing ... OK! grid levels: 3
AMGSolver begin with initial residual 0.458239 ...
converge with residual 4.32514e-13 at step 27.
L2 error = 0.000629244
(3) 計算和精確解的L2誤差(本例Dirichlet邊界條件由精確解給出)
78 double error = Functional::L2Error(solution, FunctionFunction<double>(&u), 3);
(4) 計算解和近似精確解的誤差(後述)
[學習例程2]:/usr/local/AFEPack/example/coefficient_possion_equation/
問題:-/nabla/cdot(A /nabla u) = f, 其中:A=(a_{ij})_{2*2}
u |_{/partial /Omega} = u_b
***** $ls
coefficient_possion_equation.cfg coefficient_possion_equation.net D.d README
coefficient_possion_equation.cpp CVS Makefile run
如上例:.cfg .net是OpenDx文件。本例只需關注 .cpp文件
------------------------------------------------------------------------------------
***** 比較coefficient_possion_equation.cpp和possion_equation.cpp的不同之處:
(1) 增加2*2矩陣A的定義
(2) 兩問題:possion_equation 和 coefficient_possion_equation 各自的單元剛度矩陣不同
故定義剛度矩陣的一個新派生類,虛函數 getElementMatrix(...) 重載基類的函數
class Matrix : public StiffMatrix<2, double>
{
public:
Matrix(FEMSpace<double,2>& sp) :
StiffMatrix<2,double>(sp) {};
virtual ~Matrix() {};
public:
virtual void getElementMatrix(const Element<double,2>& element0,
const Element<double,2>& element1,
const ActiveElementPairIterator<2>::State state);
};
{
public:
Matrix(FEMSpace<double,2>& sp) :
StiffMatrix<2,double>(sp) {};
virtual ~Matrix() {};
public:
virtual void getElementMatrix(const Element<double,2>& element0,
const Element<double,2>& element1,
const ActiveElementPairIterator<2>::State state);
};
[補充]:
1) C++允許子類的成員函數重載基類的成員函數
2) 運行時,依據類型確認調用哪個函數的能力稱爲多態性(polymorphism)
3) 爲指明某個成員函數具有多態性,用virtual來標誌其爲虛函數
(3) 函數 void Matrix::getElementMatrix 的定義和 BilinearOperator.templates.h 文件中 StiffMatrix<DIM,value_type,DOW,TDIM>::getElementMatrix 定義類似,只是加進了係數A,可對比看
(4) 函數getElementMatrix是提供給stiff_matrix.build();內部調用的,所以:
possion_equation.cpp
StiffMatrix<2,double> stiff_matrix(fem_space);
stiff_matrix.algebricAccuracy() = 3;
stiff_matrix.build();
stiff_matrix.algebricAccuracy() = 3;
stiff_matrix.build();
Matrix stiff_matrix(fem_space);
stiff_matrix.algebricAccuracy() = 3;
stiff_matrix.build();
stiff_matrix.algebricAccuracy() = 3;
stiff_matrix.build();