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