[学习例程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
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 = 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);
}
;
[补充]:
1) C++允许子类的成员函数重载基类的成员函数
2) 运行时,依据类型确认调用哪个函数的能力称为多态性(polymorphism)
3) 为指明某个成员函数具有多态性,用virtual来标志其为虚函数
(3) 函数 void Matrix::getElementMatrix 的定义和 BilinearOperator.templates.h 文件中 StiffMatrix::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();