21 #include "../common/common.hpp"
23 #include "nonseparable_numerical_test_kernel_trial_integrator.hpp"
25 #include "_3d_array.hpp"
26 #include "_4d_array.hpp"
27 #include "collection_of_3d_arrays.hpp"
28 #include "collection_of_4d_arrays.hpp"
31 #include "basis_data.hpp"
32 #include "conjugate.hpp"
33 #include "collection_of_basis_transformations.hpp"
34 #include "geometrical_data.hpp"
35 #include "collection_of_kernels.hpp"
36 #include "opencl_handler.hpp"
37 #include "raw_grid_geometry.hpp"
38 #include "test_kernel_trial_integral.hpp"
48 template <
typename BasisFunctionType,
typename KernelType,
49 typename ResultType,
typename GeometryFactory>
50 NonseparableNumericalTestKernelTrialIntegrator<
51 BasisFunctionType, KernelType, ResultType, GeometryFactory>::
52 NonseparableNumericalTestKernelTrialIntegrator(
53 const arma::Mat<CoordinateType>& localTestQuadPoints,
54 const arma::Mat<CoordinateType>& localTrialQuadPoints,
55 const std::vector<CoordinateType> quadWeights,
56 const GeometryFactory& testGeometryFactory,
57 const GeometryFactory& trialGeometryFactory,
58 const RawGridGeometry<CoordinateType>& testRawGeometry,
59 const RawGridGeometry<CoordinateType>& trialRawGeometry,
60 const CollectionOfShapesetTransformations<CoordinateType>& testTransformations,
61 const CollectionOfKernels<KernelType>& kernels,
62 const CollectionOfShapesetTransformations<CoordinateType>& trialTransformations,
63 const TestKernelTrialIntegral<BasisFunctionType, KernelType, ResultType>& integral,
64 const OpenClHandler& openClHandler) :
65 m_localTestQuadPoints(localTestQuadPoints),
66 m_localTrialQuadPoints(localTrialQuadPoints),
67 m_quadWeights(quadWeights),
68 m_testGeometryFactory(testGeometryFactory),
69 m_trialGeometryFactory(trialGeometryFactory),
70 m_testRawGeometry(testRawGeometry),
71 m_trialRawGeometry(trialRawGeometry),
72 m_testTransformations(testTransformations),
74 m_trialTransformations(trialTransformations),
76 m_openClHandler(openClHandler)
78 const size_t pointCount = quadWeights.size();
79 if (localTestQuadPoints.n_cols != pointCount ||
80 localTrialQuadPoints.n_cols != pointCount)
81 throw std::invalid_argument(
"NonseparableNumericalTestKernelTrialIntegrator::"
82 "NonseparableNumericalTestKernelTrialIntegrator(): "
83 "numbers of points and weights do not match");
86 template <
typename BasisFunctionType,
typename KernelType,
87 typename ResultType,
typename GeometryFactory>
88 NonseparableNumericalTestKernelTrialIntegrator<
89 BasisFunctionType, KernelType, ResultType, GeometryFactory>::
90 ~NonseparableNumericalTestKernelTrialIntegrator()
95 for (
typename BasisDataCache::const_iterator it = m_cachedTestBasisData.begin();
96 it != m_cachedTestBasisData.end(); ++it)
98 m_cachedTestBasisData.clear();
99 for (
typename BasisDataCache::const_iterator it = m_cachedTrialBasisData.begin();
100 it != m_cachedTrialBasisData.end(); ++it)
102 m_cachedTrialBasisData.clear();
105 template <
typename BasisFunctionType,
typename KernelType,
106 typename ResultType,
typename GeometryFactory>
107 const BasisData<BasisFunctionType>&
108 NonseparableNumericalTestKernelTrialIntegrator<
109 BasisFunctionType, KernelType, ResultType, GeometryFactory>::
110 basisData(ElementType type,
const Shapeset<BasisFunctionType>& shapeset)
const
112 BasisDataCache& cache =
113 type == TEST ? m_cachedTestBasisData : m_cachedTrialBasisData;
114 const CollectionOfShapesetTransformations<CoordinateType>& transformations =
115 type == TEST ? m_testTransformations : m_trialTransformations;
116 const arma::Mat<CoordinateType>& localQuadPoints =
117 type == TEST ? m_localTestQuadPoints : m_localTrialQuadPoints;
119 typename BasisDataCache::iterator it = cache.find(&shapeset);
120 if (it == cache.end()) {
127 std::auto_ptr<BasisData<BasisFunctionType> > basisData(
128 new BasisData<BasisFunctionType>);
129 size_t basisDeps = 0, geomDeps = 0;
130 transformations.addDependencies(basisDeps, geomDeps);
131 shapeset.evaluate(basisDeps, localQuadPoints, ALL_DOFS, *basisData);
139 BasisData<BasisFunctionType>* ptrBasisData = basisData.release();
140 std::pair<typename BasisDataCache::iterator, bool> result =
141 cache.insert(std::make_pair(&shapeset, ptrBasisData));
149 template <
typename BasisFunctionType,
typename KernelType,
150 typename ResultType,
typename GeometryFactory>
152 NonseparableNumericalTestKernelTrialIntegrator<
153 BasisFunctionType, KernelType, ResultType, GeometryFactory>::
155 CallVariant callVariant,
156 const std::vector<int>& elementIndicesA,
158 const Shapeset<BasisFunctionType>& basisA,
159 const Shapeset<BasisFunctionType>& basisB,
160 LocalDofIndex localDofIndexB,
161 const std::vector<arma::Mat<ResultType>*>& result)
const
163 const int pointCount = m_quadWeights.size();
164 const int elementACount = elementIndicesA.size();
166 if (result.size() != elementIndicesA.size())
167 throw std::invalid_argument(
168 "NonseparableNumericalTestKernelTrialIntegrator::integrate(): "
169 "arrays 'result' and 'elementIndicesA' must have the same number "
171 if (pointCount == 0 || elementACount == 0)
178 const int dofCountA = basisA.size();
179 const int dofCountB = localDofIndexB == ALL_DOFS ? basisB.size() : 1;
180 const int testDofCount = callVariant == TEST_TRIAL ? dofCountA : dofCountB;
181 const int trialDofCount = callVariant == TEST_TRIAL ? dofCountB : dofCountA;
183 BasisData<BasisFunctionType> testBasisData, trialBasisData;
184 GeometricalData<CoordinateType>& testGeomData = m_testGeomData.local();
185 GeometricalData<CoordinateType>& trialGeomData = m_trialGeomData.local();
187 size_t testBasisDeps = 0, trialBasisDeps = 0;
188 size_t testGeomDeps = 0, trialGeomDeps = 0;
190 m_testTransformations.addDependencies(testBasisDeps, testGeomDeps);
191 m_trialTransformations.addDependencies(trialBasisDeps, trialGeomDeps);
193 m_integral.addGeometricalDependencies(testGeomDeps, trialGeomDeps);
195 typedef typename GeometryFactory::Geometry Geometry;
197 std::auto_ptr<Geometry> geometryA, geometryB;
198 const RawGridGeometry<CoordinateType> *rawGeometryA = 0, *rawGeometryB = 0;
199 if (callVariant == TEST_TRIAL)
201 geometryA = m_testGeometryFactory.make();
202 geometryB = m_trialGeometryFactory.make();
203 rawGeometryA = &m_testRawGeometry;
204 rawGeometryB = &m_trialRawGeometry;
208 geometryA = m_trialGeometryFactory.make();
209 geometryB = m_testGeometryFactory.make();
210 rawGeometryA = &m_trialRawGeometry;
211 rawGeometryB = &m_testRawGeometry;
214 CollectionOf3dArrays<BasisFunctionType> testValues, trialValues;
215 CollectionOf3dArrays<KernelType> kernelValues;
217 for (
size_t i = 0; i < result.size(); ++i) {
219 result[i]->set_size(testDofCount, trialDofCount);
222 rawGeometryB->setupGeometry(elementIndexB, *geometryB);
223 if (callVariant == TEST_TRIAL)
225 basisA.evaluate(testBasisDeps, m_localTestQuadPoints, ALL_DOFS, testBasisData);
226 basisB.evaluate(trialBasisDeps, m_localTrialQuadPoints, localDofIndexB, trialBasisData);
227 geometryB->getData(trialGeomDeps, m_localTrialQuadPoints, trialGeomData);
228 m_trialTransformations.evaluate(trialBasisData, trialGeomData, trialValues);
232 basisA.evaluate(trialBasisDeps, m_localTrialQuadPoints, ALL_DOFS, trialBasisData);
233 basisB.evaluate(testBasisDeps, m_localTestQuadPoints, localDofIndexB, testBasisData);
234 geometryB->getData(testGeomDeps, m_localTestQuadPoints, testGeomData);
235 m_testTransformations.evaluate(testBasisData, testGeomData, testValues);
239 for (
int indexA = 0; indexA < elementACount; ++indexA)
241 rawGeometryA->setupGeometry(elementIndicesA[indexA], *geometryA);
242 if (callVariant == TEST_TRIAL)
244 geometryA->getData(testGeomDeps, m_localTestQuadPoints, testGeomData);
245 m_testTransformations.evaluate(testBasisData, testGeomData, testValues);
249 geometryA->getData(trialGeomDeps, m_localTrialQuadPoints, trialGeomData);
250 m_trialTransformations.evaluate(trialBasisData, trialGeomData, trialValues);
254 m_integral.evaluateWithNontensorQuadratureRule(
255 testGeomData, trialGeomData, testValues, trialValues,
256 kernelValues, m_quadWeights,
261 template <
typename BasisFunctionType,
typename KernelType,
262 typename ResultType,
typename GeometryFactory>
264 NonseparableNumericalTestKernelTrialIntegrator<
265 BasisFunctionType, KernelType, ResultType, GeometryFactory>::
267 const std::vector<ElementIndexPair>& elementIndexPairs,
268 const Shapeset<BasisFunctionType>& testShapeset,
269 const Shapeset<BasisFunctionType>& trialShapeset,
270 const std::vector<arma::Mat<ResultType>*>& result)
const
272 const int pointCount = m_quadWeights.size();
273 const int geometryPairCount = elementIndexPairs.size();
275 if (result.size() != elementIndexPairs.size())
276 throw std::invalid_argument(
277 "NonseparableNumericalTestKernelTrialIntegrator::integrate(): "
278 "arrays 'result' and 'elementIndicesA' must have the same number "
280 if (pointCount == 0 || geometryPairCount == 0)
285 const int testDofCount = testShapeset.size();
286 const int trialDofCount = trialShapeset.size();
289 const BasisData<BasisFunctionType>& testBasisData
290 = basisData(TEST, testShapeset);
291 const BasisData<BasisFunctionType>& trialBasisData
292 = basisData(TRIAL, trialShapeset);
293 GeometricalData<CoordinateType>& testGeomData = m_testGeomData.local();
294 GeometricalData<CoordinateType>& trialGeomData = m_trialGeomData.local();
296 size_t testBasisDeps = 0, trialBasisDeps = 0;
297 size_t testGeomDeps = 0, trialGeomDeps = 0;
299 m_testTransformations.addDependencies(testBasisDeps, testGeomDeps);
300 m_trialTransformations.addDependencies(trialBasisDeps, trialGeomDeps);
302 m_integral.addGeometricalDependencies(testGeomDeps, trialGeomDeps);
304 typedef typename GeometryFactory::Geometry Geometry;
305 std::auto_ptr<Geometry> testGeometry(m_testGeometryFactory.make());
306 std::auto_ptr<Geometry> trialGeometry(m_trialGeometryFactory.make());
308 CollectionOf3dArrays<BasisFunctionType> testValues, trialValues;
309 CollectionOf3dArrays<KernelType> kernelValues;
311 for (
size_t i = 0; i < result.size(); ++i) {
313 result[i]->set_size(testDofCount, trialDofCount);
320 for (
int pairIndex = 0; pairIndex < geometryPairCount; ++pairIndex)
322 m_testRawGeometry.setupGeometry(elementIndexPairs[pairIndex].first, *testGeometry);
323 m_trialRawGeometry.setupGeometry(elementIndexPairs[pairIndex].second, *trialGeometry);
324 testGeometry->getData(testGeomDeps, m_localTestQuadPoints, testGeomData);
325 trialGeometry->getData(trialGeomDeps, m_localTrialQuadPoints, trialGeomData);
326 m_testTransformations.evaluate(testBasisData, testGeomData, testValues);
327 m_trialTransformations.evaluate(trialBasisData, trialGeomData, trialValues);
330 m_integral.evaluateWithNontensorQuadratureRule(
331 testGeomData, trialGeomData, testValues, trialValues,
332 kernelValues, m_quadWeights,
virtual void evaluateAtPointPairs(const GeometricalData< CoordinateType > &testGeomData, const GeometricalData< CoordinateType > &trialGeomData, CollectionOf3dArrays< ValueType > &result) const =0
Evaluate the kernels at a list of (test point, trial point) pairs.
virtual void addGeometricalDependencies(size_t &testGeomDeps, size_t &trialGeomDeps) const =0
Retrieve types of geometrical data on which the kernels depend.