[筆記2.1]學習AFEPack的例程

 [學習例程1]:/usr/local/AFEPack/example/possion_equation/
問題:-/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; 

[補充]
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 $*

[補充](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);    

[運行提示信息] 其中 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 = 20const;
...
}
;
參數:
    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<2double>
{
    
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();
改爲 coefficient_possion_equation.cpp
    Matrix stiff_matrix(fem_space);
    stiff_matrix.algebricAccuracy() 
= 3;
    stiff_matrix.build();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章