dune-grid-glue  2.7.0
conformingmerge.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /*
4  * Filename: conformingmerge.hh
5  * Version: 1.0
6  * Created on: Sep 14, 2009
7  * Author: Oliver Sander
8  * ---------------------------------
9  * Project: dune-grid-glue
10  * Description: implementation of the Merger concept for conforming interfaces
11  *
12  */
19 #ifndef DUNE_GRIDGLUE_MERGING_CONFORMINGMERGE_HH
20 #define DUNE_GRIDGLUE_MERGING_CONFORMINGMERGE_HH
21 
22 #include <iomanip>
23 #include <vector>
24 #include <algorithm>
25 #include <bitset>
26 
27 #include <dune/common/fmatrix.hh>
28 #include <dune/common/fvector.hh>
29 
30 #include <dune/geometry/referenceelements.hh>
31 
33 
34 namespace Dune {
35 
36  namespace GridGlue {
37 
44 template<int dim, int dimworld, typename T = double>
46  : public StandardMerge<T,dim,dim,dimworld>
47 {
48 
49 public:
50 
51  /* E X P O R T E D T Y P E S A N D C O N S T A N T S */
52 
54  typedef T ctype;
55 
57  typedef Dune::FieldVector<T, dimworld> WorldCoords;
58 
60  typedef Dune::FieldVector<T, dim> LocalCoords;
61 
62 private:
63 
64  /* M E M B E R V A R I A B L E S */
65 
67  T tolerance_;
68 
69  typedef typename StandardMerge<T,dim,dim,dimworld>::SimplicialIntersection SimplicialIntersection;
70 
75  void computeIntersections(const Dune::GeometryType& grid1ElementType,
76  const std::vector<Dune::FieldVector<T,dimworld> >& grid1ElementCorners,
77  std::bitset<(1<<dim)>& neighborIntersects1,
78  unsigned int grid1Index,
79  const Dune::GeometryType& grid2ElementType,
80  const std::vector<Dune::FieldVector<T,dimworld> >& grid2ElementCorners,
81  std::bitset<(1<<dim)>& neighborIntersects2,
82  unsigned int grid2Index,
83  std::vector<SimplicialIntersection>& intersections);
84 
85 public:
86 
87  static constexpr T default_tolerance = 1e-4;
88 
90  tolerance_(tolerance)
91  {}
92 };
93 
94 template<int dim, int dimworld, typename T>
96 
97 template<int dim, int dimworld, typename T>
98 void ConformingMerge<dim, dimworld, T>::computeIntersections(const Dune::GeometryType& grid1ElementType,
99  const std::vector<Dune::FieldVector<T,dimworld> >& grid1ElementCorners,
100  std::bitset<(1<<dim)>& neighborIntersects1,
101  unsigned int grid1Index,
102  const Dune::GeometryType& grid2ElementType,
103  const std::vector<Dune::FieldVector<T,dimworld> >& grid2ElementCorners,
104  std::bitset<(1<<dim)>& neighborIntersects2,
105  unsigned int grid2Index,
106  std::vector<SimplicialIntersection>& intersections)
107 {
108  this->counter++;
109 
110  // A few consistency checks
111  assert((unsigned int)(Dune::ReferenceElements<T,dim>::general(grid1ElementType).size(dim)) == grid1ElementCorners.size());
112  assert((unsigned int)(Dune::ReferenceElements<T,dim>::general(grid2ElementType).size(dim)) == grid2ElementCorners.size());
113  // any intersection we may find will be the entire elements.
114  neighborIntersects1.reset();
115  neighborIntersects2.reset();
116 
117  // the intersection is either conforming or empty, hence the GeometryTypes have to match
118  if (grid1ElementType != grid2ElementType)
119  return;
120 
121  // ////////////////////////////////////////////////////////////
122  // Find correspondences between the different corners
123  // ////////////////////////////////////////////////////////////
124  std::vector<int> other(grid1ElementCorners.size(), -1);
125 
126  for (unsigned int i=0; i<grid1ElementCorners.size(); i++) {
127 
128  for (unsigned int j=0; j<grid2ElementCorners.size(); j++) {
129 
130  if ( (grid1ElementCorners[i]-grid2ElementCorners[j]).two_norm() < tolerance_ ) {
131 
132  other[i] = j;
133  break;
134 
135  }
136 
137  }
138 
139  // No corresponding grid2 vertex found for this grid1 vertex
140  if (other[i] == -1)
141  return;
142 
143  }
144 
145  // ////////////////////////////////////////////////////////////
146  // Set up the new remote intersection
147  // ////////////////////////////////////////////////////////////
148 
149  const auto& refElement = Dune::ReferenceElements<T,dim>::general(grid1ElementType);
150 
152  if (grid1ElementType.isSimplex()) {
153 
154  intersections.emplace_back(grid1Index, grid2Index);
155 
156  for (int i=0; i<refElement.size(dim); i++) {
157  intersections.back().corners0[0][i] = refElement.position(i,dim);
158  intersections.back().corners1[0][i] = refElement.position(other[i],dim);
159  }
160 
161  } else if (dim == 2 && grid1ElementType.isQuadrilateral()) {
162 
163  // split the quadrilateral into two triangles
164  const unsigned int subVertices[2][3] = {{0,1,3}, {0,3,2}};
165 
166  for (int i=0; i<2; i++) {
167 
168  SimplicialIntersection newSimplicialIntersection(grid1Index, grid2Index);
169 
170  for (int j=0; j<dim+1; j++) {
171  newSimplicialIntersection.corners0[0][j] = refElement.position(subVertices[i][j],dim);
172  newSimplicialIntersection.corners1[0][j] = refElement.position(subVertices[i][other[j]],dim);
173  }
174 
175  intersections.push_back(newSimplicialIntersection);
176 
177  }
178 
179  } else if (grid1ElementType.isHexahedron()) {
180 
181  // split the hexahedron into five tetrahedra
182  // This can be removed if ever we allow Intersections that are not simplices
183  const unsigned int subVertices[5][4] = {{0,1,3,5}, {0,3,2,6}, {4,5,0,6}, {6,7,6,3}, {6,0,5,3}};
184 
185  for (int i=0; i<5; i++) {
186 
187  SimplicialIntersection newSimplicialIntersection(grid1Index, grid2Index);
188 
189  for (int j=0; j<dim+1; j++) {
190  newSimplicialIntersection.corners0[0][j] = refElement.position(subVertices[i][j],dim);
191  newSimplicialIntersection.corners1[0][j] = refElement.position(subVertices[i][other[j]],dim);
192  }
193 
194  intersections.push_back(newSimplicialIntersection);
195 
196  }
197 
198  } else
199  DUNE_THROW(Dune::GridError, "Unsupported element type");
200 
201 }
202 
203 } // namespace GridGlue
204 
205 } // namespace Dune
206 
207 #endif // DUNE_GRIDGLUE_MERGING_CONFORMINGMERGE_HH
Dune
Definition: gridglue.hh:35
Dune::GridGlue::ConformingMerge::LocalCoords
Dune::FieldVector< T, dim > LocalCoords
the coordinate type used in this interface
Definition: conformingmerge.hh:60
Dune::GridGlue::StandardMerge
Common base class for many merger implementations: produce pairs of entities that may intersect.
Definition: standardmerge.hh:56
Dune::GridGlue::ConformingMerge::WorldCoords
Dune::FieldVector< T, dimworld > WorldCoords
the coordinate type used in this interface
Definition: conformingmerge.hh:57
Dune::GridGlue::intersections
IteratorRange<... > intersections(const GridGlue<... > &glue, const Reverse<... > &reverse=!reversed)
Iterate over all intersections of a GridGlue.
Dune::GridGlue::StandardMerge::SimplicialIntersection
typename IntersectionListProvider::SimplicialIntersection SimplicialIntersection
Definition: standardmerge.hh:81
Dune::GridGlue::ConformingMerge
Implementation of the Merger concept for conforming interfaces.
Definition: conformingmerge.hh:47
Dune::GridGlue::ConformingMerge::default_tolerance
static constexpr T default_tolerance
Definition: conformingmerge.hh:87
standardmerge.hh
Common base class for many merger implementations: produce pairs of entities that may intersect.
Dune::GridGlue::ConformingMerge::ctype
T ctype
the numeric type used in this interface
Definition: conformingmerge.hh:54
Dune::GridGlue::ConformingMerge::ConformingMerge
ConformingMerge(T tolerance=default_tolerance)
Definition: conformingmerge.hh:89