void DefaultTestTrialIntegral<IntegrandFunctor>::evaluate( const GeometricalData<CoordinateType>& geomData, const CollectionOf3dArrays<BasisFunctionType>& testValues, const CollectionOf3dArrays<BasisFunctionType>& trialValues, const std::vector<CoordinateType>& weights, arma::Mat<ResultType>& result) const { const size_t pointCount = weights.size(); assert(testValues.size() == 1); assert(trialValues.size() == 1); // We don't care about the number of rows of testValues[0] and trialValues[0] // -- it's up to the integrand functor const size_t testDofCount = testValues[0].extent(1); const size_t trialDofCount = trialValues[0].extent(1); assert(testValues[0].extent(2) == pointCount); assert(trialValues[0].extent(2) == pointCount); for (size_t trialDof = 0; trialDof < trialDofCount; ++trialDof) for (size_t testDof = 0; testDof < testDofCount; ++testDof) { ResultType sum = 0.; for (size_t point = 0; point < pointCount; ++point) sum += m_functor.evaluate( geomData.const_slice(point), testValues.const_slice(testDof, point), trialValues.const_slice(trialDof, point)) * geomData.integrationElements(point) * weights[point]; result(testDof, trialDof) = sum; } }
void DefaultTestKernelTrialIntegral<IntegrandFunctor>:: evaluateWithTensorQuadratureRule( const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, const CollectionOf3dArrays<BasisFunctionType> &testValues, const CollectionOf3dArrays<BasisFunctionType> &trialValues, const CollectionOf4dArrays<KernelType> &kernelValues, const std::vector<CoordinateType> &testQuadWeights, const std::vector<CoordinateType> &trialQuadWeights, Matrix<ResultType> &result) const { // Evaluate constants const size_t testDofCount = testValues[0].extent(1); const size_t trialDofCount = trialValues[0].extent(1); const size_t testPointCount = testQuadWeights.size(); const size_t trialPointCount = trialQuadWeights.size(); // Assert that array dimensions are correct for (size_t i = 0; i < kernelValues.size(); ++i) { assert(kernelValues[i].extent(2) == testPointCount); assert(kernelValues[i].extent(3) == trialPointCount); } for (size_t i = 0; i < testValues.size(); ++i) assert(testValues[i].extent(2) == testPointCount); for (size_t i = 0; i < trialValues.size(); ++i) assert(trialValues[i].extent(2) == trialPointCount); assert(result.rows() == testDofCount); assert(result.cols() == trialDofCount); // Integrate for (size_t trialDof = 0; trialDof < trialDofCount; ++trialDof) for (size_t testDof = 0; testDof < testDofCount; ++testDof) { ResultType sum = 0.; for (size_t trialPoint = 0; trialPoint < trialPointCount; ++trialPoint) { const CoordinateType trialWeight = trialGeomData.integrationElements(trialPoint) * trialQuadWeights[trialPoint]; ResultType partialSum = 0.; for (size_t testPoint = 0; testPoint < testPointCount; ++testPoint) { const CoordinateType testWeight = testGeomData.integrationElements(testPoint) * testQuadWeights[testPoint]; partialSum += m_functor.evaluate( testGeomData.const_slice(testPoint), trialGeomData.const_slice(trialPoint), testValues.const_slice(testDof, testPoint), trialValues.const_slice(trialDof, trialPoint), kernelValues.const_slice(testPoint, trialPoint)) * testWeight; } sum += partialSum * trialWeight; } result(testDof, trialDof) = sum; } }
void evaluateOnGridPeter(std::string str, const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, CollectionOf4dArrays<ValueType> &result) const { const size_t testPointCount = testGeomData.pointCount(); const size_t trialPointCount = trialGeomData.pointCount(); const size_t kernelCount = m_functor.kernelCount(); result.set_size(kernelCount); for (size_t k = 0; k < kernelCount; ++k) result[k].set_size(m_functor.kernelRowCount(k), m_functor.kernelColCount(k), testPointCount, trialPointCount); #pragma ivdep for (size_t trialIndex = 0; trialIndex < trialPointCount; ++trialIndex) for (size_t testIndex = 0; testIndex < testPointCount; ++testIndex) // m_functor.evaluate(testGeomData.const_slice(testIndex), trialGeomData.const_slice(trialIndex), result.slice(testIndex, trialIndex).self()); m_functor.evaluatePeter(str,testGeomData.const_slice(testIndex), trialGeomData.const_slice(trialIndex), result.slice(testIndex, trialIndex).self()); }
void DefaultTestKernelTrialIntegral<IntegrandFunctor>:: evaluateWithNontensorQuadratureRule( const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, const CollectionOf3dArrays<BasisFunctionType> &testValues, const CollectionOf3dArrays<BasisFunctionType> &trialValues, const CollectionOf3dArrays<KernelType> &kernelValues, const std::vector<CoordinateType> &quadWeights, Matrix<ResultType> &result) const { // Evaluate constants const size_t testDofCount = testValues[0].extent(1); const size_t trialDofCount = trialValues[0].extent(1); const size_t pointCount = quadWeights.size(); // Assert that array dimensions are correct for (size_t i = 0; i < kernelValues.size(); ++i) assert(kernelValues[i].extent(2) == pointCount); for (size_t i = 0; i < testValues.size(); ++i) assert(testValues[i].extent(2) == pointCount); for (size_t i = 0; i < trialValues.size(); ++i) assert(trialValues[i].extent(2) == pointCount); // Integrate for (size_t trialDof = 0; trialDof < trialDofCount; ++trialDof) for (size_t testDof = 0; testDof < testDofCount; ++testDof) { ResultType sum = 0.; for (size_t point = 0; point < pointCount; ++point) sum += m_functor.evaluate(testGeomData.const_slice(point), trialGeomData.const_slice(point), testValues.const_slice(testDof, point), trialValues.const_slice(trialDof, point), kernelValues.const_slice(point)) * (testGeomData.integrationElements(point) * trialGeomData.integrationElements(point) * quadWeights[point]); result(testDof, trialDof) = sum; } }
void DefaultCollectionOfShapesetTransformations<Functor>::evaluateImpl( const BasisData<ValueType> &basisData, const GeometricalData<CoordinateType> &geomData, CollectionOf3dArrays<ValueType> &result) const { const int pointCount = basisData.pointCount(); const int functionCount = basisData.functionCount(); const int transformationCount = m_functor.transformationCount(); result.set_size(transformationCount); for (int t = 0; t < transformationCount; ++t) result[t].set_size(m_functor.resultDimension(t), functionCount, pointCount); for (int p = 0; p < pointCount; ++p) for (int f = 0; f < functionCount; ++f) m_functor.evaluate(basisData.const_slice(f, p), geomData.const_slice(p), result.slice(f, p).self()); }
void NumericalTestTrialIntegrator<BasisFunctionType, ResultType, GeometryFactory>::integrate( const std::vector<int>& elementIndices, const Basis<BasisFunctionType>& testBasis, const Basis<BasisFunctionType>& trialBasis, arma::Cube<ResultType>& result) const { const size_t pointCount = m_localQuadPoints.n_cols; const size_t elementCount = elementIndices.size(); if (pointCount == 0 || elementCount == 0) return; // TODO: in the (pathological) case that pointCount == 0 but // elementCount != 0, set elements of result to 0. // Evaluate constants const int componentCount = m_testTransformations.resultDimension(0); const int testDofCount = testBasis.size(); const int trialDofCount = trialBasis.size(); // if (m_trialTransformations.codomainDimension() != componentCount) // throw std::runtime_error("NumericalTestTrialIntegrator::integrate(): " // "test and trial functions " // "must have the same number of components"); BasisData<BasisFunctionType> testBasisData, trialBasisData; GeometricalData<CoordinateType> geomData; size_t testBasisDeps = 0, trialBasisDeps = 0; size_t geomDeps = INTEGRATION_ELEMENTS; m_testTransformations.addDependencies(testBasisDeps, geomDeps); m_trialTransformations.addDependencies(trialBasisDeps, geomDeps); typedef typename GeometryFactory::Geometry Geometry; std::auto_ptr<Geometry> geometry(m_geometryFactory.make()); CollectionOf3dArrays<BasisFunctionType> testValues, trialValues; result.set_size(testDofCount, trialDofCount, elementCount); testBasis.evaluate(testBasisDeps, m_localQuadPoints, ALL_DOFS, testBasisData); trialBasis.evaluate(trialBasisDeps, m_localQuadPoints, ALL_DOFS, trialBasisData); // Iterate over the elements for (size_t e = 0; e < elementCount; ++e) { m_rawGeometry.setupGeometry(elementIndices[e], *geometry); geometry->getData(geomDeps, m_localQuadPoints, geomData); m_testTransformations.evaluate(testBasisData, geomData, testValues); m_trialTransformations.evaluate(trialBasisData, geomData, trialValues); for (int trialDof = 0; trialDof < trialDofCount; ++trialDof) for (int testDof = 0; testDof < testDofCount; ++testDof) { ResultType sum = 0.; for (size_t point = 0; point < pointCount; ++point) for (int dim = 0; dim < componentCount; ++dim) sum += m_quadWeights[point] * geomData.integrationElements(point) * conjugate(testValues[0](dim, testDof, point)) * trialValues[0](dim, trialDof, point); result(testDof, trialDof, e) = sum; } } }
//Peter: //template <typename Functor> //template <template <typename T> class CollectionOf2dSlicesOfNdArrays> void evaluateAtPointPairsPeter(std::string str, const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, CollectionOf3dArrays<ValueType> &result) const { assert(testGeomData.pointCount() == trialGeomData.pointCount()); const size_t pointCount = testGeomData.pointCount(); const size_t kernelCount = m_functor.kernelCount(); result.set_size(kernelCount); //std::cout << "evalAtPointPairsPeter\n"; // CoordinateType m_waveNumber = m_functor.waveNumber(); // ValueType m_waveNumber = m_functor.waveNumber(); // std::string::size_type sz; // alias of size_t // double earth = std::stod (orbits,&sz); // double moon = std::stod (orbits.substr(sz)); // ValueType waveK = static_cast<CoordinateType>(std::stod(str,&sz) ); // std::cerr << "In defColKern, str = " << str << std::endl; // ValueType waveK = static_cast<CoordinateType>(str); for (size_t k = 0; k < kernelCount; ++k) result[k].set_size(m_functor.kernelRowCount(k), m_functor.kernelColCount(k), pointCount); for (size_t p = 0; p < pointCount; ++p) { /* if(std::is_same<Functor,ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>>::value) { std::cout << "Right kernel" << std::endl; m_functor.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); } else { std::cerr << "Wrong kernel" << std::endl; std::terminate(); }*/ // (m_functor*)->evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); //std::unique_ptr<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor)->evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); // const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& tmp = dynamic_cast<const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& >(m_functor); // ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> tmp = static_cast<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor); // static_cast<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor).evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); m_functor.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); // const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> bla = dynamic_cast<const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& > (m_functor); // bla.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self()); //// m_functor.evaluate(testGeomData.const_slice(p), //// trialGeomData.const_slice(p), result.slice(p).self()); /* const ConstGeometricalDataSlice<CoordinateType> &testGeomDataSl = testGeomData.const_slice(p); const ConstGeometricalDataSlice<CoordinateType> &trialGeomDataSl = trialGeomData.const_slice(p); // CollectionOf2dSlicesOfNdArrays<ValueType> &resultSl = result.slice(p).self(); CollectionOf2dSlicesOf3dArrays<ValueType> &resultSl = result.slice(p).self(); const int coordCount = 3; CoordinateType sum = 0; for (int coordIndex = 0; coordIndex < coordCount; ++coordIndex) { CoordinateType diff = testGeomDataSl.global(coordIndex) - trialGeomDataSl.global(coordIndex); sum += diff * diff; } CoordinateType distance = sqrt(sum); if (distance >= 2) { std::cerr << "Error, 2 <= distance =" << distance << std::endl; } CoordinateType wind = static_cast<CoordinateType>(1.0); CoordinateType cuto = static_cast<CoordinateType>(0.1); CoordinateType cutoSP = static_cast<CoordinateType>(0.3); if (false) { if (distance >= cuto*2) { wind = static_cast<CoordinateType>(0.0); } else if (distance >= cuto) { wind = exp(2*exp(-cuto/(distance-2*cuto) )/( (distance-2*cuto)/cuto-1) ); } } // result[0](0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-m_waveNumber * distance)*wind; // result(0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-m_waveNumber * distance)*wind; resultSl[0](0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-waveK * distance)*wind; */ } }