BEM++  2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
default_local_assembler_for_grid_functions_on_surfaces_imp.hpp
1 // Copyright (C) 2011-2012 by the Bem++ Authors
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 // Keep IDEs happy
22 #include "default_local_assembler_for_grid_functions_on_surfaces.hpp"
23 
24 #include "../common/common.hpp"
25 
26 #include "numerical_test_function_integrator.hpp"
27 #include "quadrature_descriptor_selector_for_grid_functions.hpp"
28 #include "single_quadrature_rule_family.hpp"
29 
30 #include <set>
31 #include <utility>
32 
33 namespace Fiber
34 {
35 
36 template <typename BasisFunctionType, typename UserFunctionType,
37  typename ResultType, typename GeometryFactory>
38 DefaultLocalAssemblerForGridFunctionsOnSurfaces<
39 BasisFunctionType, UserFunctionType, ResultType, GeometryFactory>::
40 DefaultLocalAssemblerForGridFunctionsOnSurfaces(
41  const shared_ptr<const GeometryFactory>& geometryFactory,
42  const shared_ptr<const RawGridGeometry<CoordinateType> >& rawGeometry,
43  const shared_ptr<const std::vector<const Shapeset<BasisFunctionType>*> >& testShapesets,
44  const shared_ptr<const CollectionOfShapesetTransformations<CoordinateType> >& testTransformations,
45  const shared_ptr<const Function<UserFunctionType> >& function,
46  const shared_ptr<const OpenClHandler>& openClHandler,
47  const shared_ptr<const QuadratureDescriptorSelectorForGridFunctions<CoordinateType> >& quadDescSelector,
48  const shared_ptr<const SingleQuadratureRuleFamily<CoordinateType> >& quadRuleFamily) :
49  m_geometryFactory(geometryFactory),
50  m_rawGeometry(rawGeometry),
51  m_testShapesets(testShapesets),
52  m_testTransformations(testTransformations),
53  m_function(function),
54  m_openClHandler(openClHandler),
55  m_quadDescSelector(quadDescSelector),
56  m_quadRuleFamily(quadRuleFamily)
57 {
58 }
59 
60 template <typename BasisFunctionType, typename UserFunctionType,
61  typename ResultType, typename GeometryFactory>
62 DefaultLocalAssemblerForGridFunctionsOnSurfaces<
63 BasisFunctionType, UserFunctionType, ResultType, GeometryFactory>::
64 ~DefaultLocalAssemblerForGridFunctionsOnSurfaces()
65 {
66  // Note: obviously the destructor is assumed to be called only after
67  // all threads have ceased using the assembler!
68 
69  for (typename IntegratorMap::const_iterator it = m_testFunctionIntegrators.begin();
70  it != m_testFunctionIntegrators.end(); ++it)
71  delete it->second;
72  m_testFunctionIntegrators.clear();
73 }
74 
75 template <typename BasisFunctionType, typename UserFunctionType,
76  typename ResultType, typename GeometryFactory>
77 void
78 DefaultLocalAssemblerForGridFunctionsOnSurfaces<
79 BasisFunctionType, UserFunctionType, ResultType, GeometryFactory>::
80 evaluateLocalWeakForms(
81  const std::vector<int>& elementIndices,
82  std::vector<arma::Col<ResultType> >& result)
83 {
85 
86  const int elementCount = elementIndices.size();
87  result.resize(elementCount);
88 
89  // Find cached matrices; select integrators to calculate non-cached ones
90  typedef std::pair<const Integrator*, const Shapeset*> QuadVariant;
91  std::vector<QuadVariant> quadVariants(elementCount);
92 
93  for (int testIndex = 0; testIndex < elementCount; ++testIndex)
94  {
95  const int activeTestElementIndex = elementIndices[testIndex];
96  const Integrator* integrator =
97  &selectIntegrator(activeTestElementIndex);
98  quadVariants[testIndex] =
99  QuadVariant(integrator, (*m_testShapesets)[activeTestElementIndex]);
100  }
101 
102  // Integration will proceed in batches of element pairs having the same
103  // "quadrature variant", i.e. integrator and test shapeset
104 
105  // Find all the unique quadrature variants present
106  typedef std::set<QuadVariant> QuadVariantSet;
107  // Set of unique quadrature variants
108  QuadVariantSet uniqueQuadVariants(quadVariants.begin(), quadVariants.end());
109 
110  std::vector<int> activeElementIndices;
111  activeElementIndices.reserve(elementCount);
112 
113  // Now loop over unique quadrature variants
114  for (typename QuadVariantSet::const_iterator it = uniqueQuadVariants.begin();
115  it != uniqueQuadVariants.end(); ++it)
116  {
117  const QuadVariant activeQuadVariant = *it;
118  const Integrator& activeIntegrator = *it->first;
119  const Shapeset& activeTestShapeset = *it->second;
120 
121  // Find all the test elements for which quadrature should proceed
122  // according to the current quadrature variant
123  activeElementIndices.clear();
124  for (int e = 0; e < elementCount; ++e)
125  if (quadVariants[e] == activeQuadVariant)
126  activeElementIndices.push_back(elementIndices[e]);
127 
128  // Integrate!
129  arma::Mat<ResultType> localResult;
130  activeIntegrator.integrate(activeElementIndices,
131  activeTestShapeset,
132  localResult);
133 
134  // Distribute the just calculated integrals into the result array
135  // that will be returned to caller
136  int i = 0;
137  for (int e = 0; e < elementCount; ++e)
138  if (quadVariants[e] == activeQuadVariant)
139  result[e] = localResult.col(i++);
140  }
141 }
142 
143 template <typename BasisFunctionType, typename UserFunctionType,
144  typename ResultType, typename GeometryFactory>
147 BasisFunctionType, UserFunctionType, ResultType, GeometryFactory>::
148 selectIntegrator(int elementIndex)
149 {
151  m_quadDescSelector->quadratureDescriptor(elementIndex);
152  return getIntegrator(desc);
153 }
154 
155 template <typename BasisFunctionType, typename UserFunctionType,
156  typename ResultType, typename GeometryFactory>
157 const TestFunctionIntegrator<BasisFunctionType, ResultType>&
158 DefaultLocalAssemblerForGridFunctionsOnSurfaces<
159 BasisFunctionType, UserFunctionType, ResultType, GeometryFactory>::
160 getIntegrator(const SingleQuadratureDescriptor& desc)
161 {
162  typename IntegratorMap::iterator it = m_testFunctionIntegrators.find(desc);
163  if (it != m_testFunctionIntegrators.end())
164  {
165  // std::cout << "getIntegrator(: " << index << "): integrator found" << std::endl;
166  return *it->second;
167  }
168  // std::cout << "getIntegrator(: " << index << "): integrator not found" << std::endl;
169 
170  // Integrator doesn't exist yet and must be created.
171  arma::Mat<CoordinateType> points;
172  std::vector<CoordinateType> weights;
173  m_quadRuleFamily->fillQuadraturePointsAndWeights(desc, points, weights);
174 
175  typedef NumericalTestFunctionIntegrator<BasisFunctionType, UserFunctionType,
176  ResultType, GeometryFactory> ConcreteIntegrator;
177  Integrator* integrator(
178  new ConcreteIntegrator(points, weights,
179  *m_geometryFactory, *m_rawGeometry,
180  *m_testTransformations, *m_function,
181  *m_openClHandler));
182 
183  // Attempt to insert the newly created integrator into the map
184  std::pair<typename IntegratorMap::iterator, bool> result =
185  m_testFunctionIntegrators.insert(std::make_pair(desc, integrator));
186  if (result.second)
187  // Insertion succeeded. The newly created integrator will be deleted in
188  // our own destructor
189  ;
190  else
191  // Insertion failed -- another thread was faster. Delete the newly
192  // created integrator.
193  delete integrator;
194 
195  // Return pointer to the integrator that ended up in the map.
196  return *result.first->second;
197 }
198 
199 } // namespace Fiber
virtual int size() const =0
Return the number of shape functions.
Integration of products of test functions and arbitrary functions over elements.
Definition: test_function_integrator.hpp:41
Definition: default_local_assembler_for_grid_functions_on_surfaces.hpp:51
Collection of shape functions defined on a reference element.
Definition: default_local_assembler_for_operators_on_surfaces_utilities.hpp:34
Parameters of a quadrature rule used in the evaluation of integrals over single elements.
Definition: single_quadrature_descriptor.hpp:34