用于数值积分的单例类
用于数值积分的单例类
引言
数值积分在有限元空间中是有限元计算中最常用的过程之一,因此迫切需要尽可能地减少计算机资源的消耗。因此,我为我的有限元库开发了一个数值求积的单例类,因为作为单例,所有的构造和析构过程以及计算过程中的坐标和每个求积点的权重都只进行一次,贯穿整个有限元计算过程。此外,该类的可重用性和可扩展性也经过了仔细考虑。
背景
1. 设计
存在许多数值积分方法,具有不同的求积策略、不同的维度和不同的阶数。可能很少考虑将其实现为单例。在这项工作中,求积类被设计为模板类,如下所示:
template <
unsigned int n1, QuadratureScheme q1=GaussLegendre,
unsigned int n2=0, QuadratureScheme q2=GaussLegendre,
unsigned int n3=0, QuadratureScheme q3=GaussLegendre,
unsigned int n4=0, QuadratureScheme q4=GaussLegendre,
unsigned int n5=0, QuadratureScheme q5=GaussLegendre >
class Quadrature;
因此,任何具有强类型的指定类都可以成为单例类。采用了S. Meyers[1]的单例模式。
2. 可重用性
采用了如下模板函数:
template<typename T, class coordinate> T Integrate( T (*)(coordinate) ) const;
template<typename T, class C, class coordinate> T Integrate( C, T (C::*)(coordinate) ) const;
因此,它可以很容易地被任何类、任何函数,以及任何返回类型和任何类型的参数调用。
3. 可扩展性
采用了Alexandrescu[2]的工厂模式来生成各种类型的一维求积类。用户可以添加他们自己 QuadrarureBase 类的派生类,而无需修改程序的其他部分。
4. 限制
最多可计算五维积分。由于它最初是为有限元软件开发的,因此三维积分就足够了。
积分范围在 -1 到 1 之间。这在有限元计算中通常使用。当然,它可以很容易地扩展到任意范围。
使用代码
要使用这个类,只需将文件 "quadrature.h" 包含到你的项目中即可。
进行积分计算的代码如下所示:
#include <iostream> #include <stdlib.h> #include "quadrature.h" using namespace GenericField; struct QuadratureTest { double afunction(double x,double y) {return x*x+y*y;} }; double bfunction(double x,double y) {return x-y;} int main(int argc, char *argv[]) { double a=Quadrature< 2,GaussLegendre,2,GaussLegendre >::Instance().Integrate<double>( &bfunction ); typedef double (QuadratureTest::*PFN)(double,double); PFN pfn=&QuadratureTest::afunction; QuadratureTest atest; double b=Quadrature< 2,GaussLegendre,2,GaussLegendre >::Instance().Integrate( atest, pfn ); std::cout << "Sucess: " << a << " "<< b << std::endl; return 0; }
此示例文件和 VS2005 项目文件包含在压缩文件中。
参考文献
1. S. Meyers: Effective C++, Addison Wesley 1997
2. A. Alexandrescu: Modern C++ Design: Generic Programming and Design Patterns Applied, Addison Wesley 2001