在有限元计算中,数值积分是最常用的过程之一,因此需要尽可能少地使用计算机资源。因此,为有限元库开发了一个数值积分的单例类,因为作为单例,所有构造和销毁过程以及计算坐标和每个积分点的权重的过程在整个有限元计算过程中只执行一次。此外,这个类的可重用性和可扩展性也经过了仔细考虑。
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]的工厂模式来生成各种类型的一维积分类。用户可以添加他们自己的QuadratureBase类的派生类,而无需修改程序的其他部分。
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 << "Success: " << a << " " << b << std::endl;
return 0;
}
示例文件和VS2005项目文件包含在压缩文件中。