Introduction
Numerical integration along finite element space is one of the most frequently used processes in finite element calculation and is therefore in much needs of adopting computer resources as less as possible. Therefore, I developed a singleton class of numerical quadrature for my finite element library because as a singleton, all construction and destruction processes and process in calculation coordinate and weights of each quadrature point are carried out only one time throughout all finite element calculation process. Besides, the reusability and expendability of this class is also carefully considered.
Background
1. Design
There are many numerical integration methods with different quadrature strategies, different dimensions and different ranks. It maybe one of the most important reason that little consider to implement it as singleton. In this work, the quadrature class is design as a templated class like
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;
Therefore, any specified class is with strong type could become a singleton class. The singleton pattern of S. Meyers[1] is adopted.
2. Reusability
Template functions like
template<typename T, class coordinate> T Integrate( T (*)(coordinate) ) const;
template<typename T, class C, class coordinate> T Integrate( C, T (C::*)(coordinate) ) const;
is adopted. It can be therefore easily be called by any class, any function with any return type and any types of augument.
3. Extendability
Factory pattern of Alexandrescu[2] is adopted to generate various type of one-dimensional quadrature class. Users can add their own derivative class of QuadrarureBase class with no needs of modification in other parts of the program.
4. Limitation
Integral calculation up to five dimensions. Because it is originally developed for finite element software, three dimensional integral is enough.
Integral over range between -1 to 1. It is typical used in finite element calculation. Of course it can be easily extended to any arbitrary ranges.
Using the code
To use this calss, just include file "quadrature.h" into your project.
To do integral calculation, the code would be like
#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;
}
This sample file and VS2005 project file are included in the compressed file.
References
1. S. Meyers: Effective C++, Addison Wesley 1997
2. A. Alexandrescu: Modern C++ Design: Generic Programming and Design Patterns Applied, Addison Wesley 2001