GaussQuadratureTetrahedron::GaussQuadratureTetrahedron(size_t order) { GaussLegendre quadRule = GaussLegendre(order); GaussJacobi10 quadRule10 = GaussJacobi10(order); GaussJacobi20 quadRule20 = GaussJacobi20(order); m_order = std::min(quadRule.order(), std::min(quadRule10.order(), quadRule20.order())); m_numPoints = quadRule.size() * quadRule10.size() * quadRule20.size(); position_type* pvPoint = new position_type[m_numPoints]; weight_type* pvWeight = new weight_type[m_numPoints]; size_t cnt = 0; for(size_t i = 0; i < quadRule20.size(); i++) { for(size_t j = 0; j < quadRule10.size(); j++) { for(size_t k = 0; k < quadRule.size(); k++, cnt++) { pvPoint[cnt][0] = quadRule20.point(i)[0]; pvPoint[cnt][1] = (1.0 - quadRule20.point(i)[0] ) * quadRule10.point(j)[0]; pvPoint[cnt][2] = (1.0 - quadRule20.point(i)[0]) * (1.0 - quadRule10.point(j)[0]) * quadRule.point(k)[0]; pvWeight[cnt] = quadRule20.weight(i) * quadRule10.weight(j) * quadRule.weight(k); } } } m_pvPoint = pvPoint; m_pvWeight = pvWeight; };
GaussQuadratureQuadrilateral::GaussQuadratureQuadrilateral(size_t order) { GaussLegendre quadRule = GaussLegendre(order); m_order = std::min(quadRule.order(), quadRule.order()); m_numPoints = quadRule.size() * quadRule.size(); position_type* pvPoint = new position_type[m_numPoints]; weight_type* pvWeight = new weight_type[m_numPoints]; size_t cnt = 0; for(size_t i = 0; i < quadRule.size(); i ++) { for(size_t j = 0; j < quadRule.size(); j++, cnt++) { pvPoint[cnt][0] = quadRule.point(i)[0]; pvPoint[cnt][1] = quadRule.point(j)[0]; pvWeight[cnt] = quadRule.weight(i) * quadRule.weight(j); } } m_pvPoint = pvPoint; m_pvWeight = pvWeight; };
static typename UnknownT::NumberT integrateComplex( const UnknownT& unknown, const CoordinatesInterface<DIM, typename UnknownT::NumberT>& geom, const std::vector<int>& directions ) { static const int QUAD_ORDER = UnknownT::ORDER + 1; static const int NUM = GaussLegendre<QUAD_ORDER, NumberT>::NUM; assert(DIM > 1); // integrate the the copy along direction GaussLegendre<QUAD_ORDER, NumberT> quad; std::array<int, DIM> indexSizes; indexSizes.fill(int(quad.size())); auto indices = MathsUtilities::allPermutations<DIM>(indexSizes); // The integral of the unknown in the directions // we to integrate in ValueT integral(0.0); for (auto interval : unknown.intervals()) { auto minima = interval.minima(); auto maxima = interval.maxima(); auto nodes = QuadratureOps<DIM, QUAD_ORDER, NumberT>:: nodes(quad, minima, maxima); auto weights = QuadratureOps<DIM, QUAD_ORDER, NumberT>:: weights(quad, minima, maxima); for (auto index : indices) { auto locationArray = ContainerUtilities:: select<DIM, NUM, NumberT>(nodes, index); auto allWeights = ContainerUtilities:: select<DIM, NUM, NumberT>(weights, index); Vector<DIM, NumberT> location(locationArray); assert(interval.isInside(location)); auto directionWeights = ContainerUtilities:: select<DIM, NumberT>(allWeights, directions); auto weight = ContainerUtilities:: product<NumberT>(directionWeights); integral += weight * unknown.value(directions, location) * geom.jacobian(Contravariant<DIM, NumberT>(location)); } } static_assert(NUM > 0, "NUM must be greater than zero"); return integral / NUM; }