Programming tasks to Scientific Computing I
adaptiveTriangMesh.h
Go to the documentation of this file.
1 #ifndef __ADAPTIVETRIANGMESH_H
2 #define __ADAPTIVETRIANGMESH_H
3 
4 #include <triangMesh.h>
5 
7 typedef short LocalIndex;
8 typedef int GlobalIndex;
9 const int IndexNotSet = -1;
10 
11 template <typename DomVecType>
13  int globalIndices[2];
15 };
16 
17 namespace shellFE
18 {
19 
20 template< typename DataTypeContainer, typename TriangleType >
21 class AdaptiveTriangMesh : public TriangMesh<DataTypeContainer, TriangleType>
22 {
23 public:
26  typedef typename DataTypeContainer::DomVecType DomVecType;
27  typedef typename DataTypeContainer::Point3DType Point3DType;
28  typedef typename DataTypeContainer::Indices3DType Indices3DType;
30  typedef typename DataTypeContainer::MaskType MaskType;
31  typedef std::vector< Indices3DType > VertexIndicesType;
32  typedef std::vector< Point3DType > VertexCoordsType;
33 
40  {
42 
43  protected:
44  const MeshType & _mesh;
48 
49  public:
56  DartIterator(const MeshType &Mesh, GlobalIndex triangleIndex, LocalIndex localEdgeIndex, LocalIndex localNodeIndex) :
57  _mesh(Mesh), _triangle (triangleIndex), _node(localNodeIndex), _edge(localEdgeIndex) {}
58 
64  DartIterator(const MeshType &Mesh, GlobalIndex triangleIndex, LocalIndex localEdgeIndex) :
65  _mesh(Mesh), _triangle (triangleIndex), _node((localEdgeIndex + 1) % 3), _edge(localEdgeIndex) {}
66 
67  void set ( const GlobalIndex triangle, const LocalIndex edge, const LocalIndex node )
68  {
69  _triangle = triangle;
70  _node = node;
71  _edge = edge;
72  }
73 
75  {
76  return _triangle;
77  }
78 
80  {
81  return _mesh.getTriangNodeIdx( _triangle, _node );
82  }
83 
85  {
86  return _node;
87  }
88 
90  {
91  return _edge;
92  }
93 
95  {
96  return 3 - (_node + _edge);
97  }
98 
100  {
101  return 3 - (_node + _edge);
102  }
103 
105  {
106  return _mesh.getTriangNodeIdx( _triangle, getNextNodeLocalIndex() );
107  }
108 
110  {
111  return _mesh.getNeighbour( _triangle, _edge );
112  }
113 
115  template<typename DartIteratorType>
116  LocalIndex getCommonNodeLocalIndex(const DartIteratorType & d) const
117  {
118  if(_triangle != d.getGlobalTriangleIndex())
119  throw std::invalid_argument( aol::strprintf("T=%d, but this->tringle = %d. In File %s at line %d.", d.getGlobalTriangleIndex(), _triangle, __FILE__, __LINE__).c_str() );
120  if ( _edge == d.getLocalEdgeIndex() )
121  throw std::invalid_argument( aol::strprintf("points to same edge=. In File %s at line %d.", __FILE__, __LINE__).c_str() );
122  return 3 - ( getLocalEdgeIndex() + d.getLocalEdgeIndex() );
123  }
124 
126  template<typename DartIteratorType>
127  GlobalIndex getCommonNodeGlobalIndex(const DartIteratorType & d) const
128  {
129  if ( getGlobalNodeIndex() == d.getGlobalNodeIndex() || getGlobalNodeIndex() == d.getNextNodeGlobalIndex() )
130  return getGlobalNodeIndex();
131  if ( getNextNodeGlobalIndex() == d.getGlobalNodeIndex() || getNextNodeGlobalIndex() == d.getNextNodeGlobalIndex() )
132  return getNextNodeGlobalIndex();
133  throw std::invalid_argument( aol::strprintf("Dart d and *this have no node in common. In File %s at line %d.", __FILE__, __LINE__).c_str() );
134  return -1;
135  }
136 
137  void print() const
138  {
139  cerr << "triangle = " << _triangle << ", node = " << _node << ", edge = " << _edge << endl;
140  }
141 
143  bool canFlipTriangle() const
144  {
145  return this->getNextTriangleIndex() != IndexNotSet ;
146  }
147 
150  {
151  if( !canFlipTriangle() )
152  throw std::invalid_argument( aol::strprintf("Cannot flip triangle. In File %s at line %d.", __FILE__, __LINE__).c_str() );
153 
154  GlobalIndex newTriangleIndex = getNextTriangleIndex();
155  GlobalIndex globalNodeIndex = _mesh.getTriangNodeIdx( _triangle, _node );
156  GlobalIndex globalOtherNodesIndex = _mesh.getTriangNodeIdx( _triangle, 3 - (_node + _edge) );
157 
158  // find out which node of the new triangle is ours
159  LocalIndex newNodeIndex = IndexNotSet;
160  for (LocalIndex i = 0; i < 3; ++i) {
161  if ( _mesh.getTriangNodeIdx( newTriangleIndex, i) == globalNodeIndex ) {
162  newNodeIndex = i;
163  break;
164  }
165  }
166 
167  // find out which node of the new triangle lies on our edge
168  LocalIndex newOtherNodesIndex = IndexNotSet;
169  for (LocalIndex i = 1; i < 3; ++i) {
170  if ( _mesh.getTriangNodeIdx( newTriangleIndex,(newNodeIndex + i) % 3 ) == globalOtherNodesIndex ) {
171  newOtherNodesIndex = (newNodeIndex + i) % 3;
172  break;
173  }
174  }
175 
176  if ( min( newNodeIndex, newOtherNodesIndex ) < 0 )
177  throw std::invalid_argument( aol::strprintf( "newTriang should neighbour of _triangle but has no common node .In File %s at line %d.", __FILE__, __LINE__ ).c_str() );
178 
179  LocalIndex newEdgeIndex = (-(newNodeIndex + newOtherNodesIndex)) % 3;
180  if (newEdgeIndex < 0) newEdgeIndex += 3;
181 
182  // all information found, now set:
183  _triangle = newTriangleIndex;
184  _node = newNodeIndex;
185  _edge = newEdgeIndex;
186  }
187 
189  void flipNode()
190  {
191  _node = getNextNodeLocalIndex();
192  }
193 
195  void flipEdge()
196  {
197  _edge = getNextEdgeLocalIndex();
198  }
199  };
200 
201 protected:
202  std::vector<bool> _markedForRefinement;
203  std::map< int, ParentInformation<DomVecType> > _interpolationMap;
204 
205 public:
206  AdaptiveTriangMesh ( const string& fileName ) :
207  TriangMesh<DataTypeContainer, TriangleType >( fileName ),
208  _markedForRefinement( this->getNumTriangs(), false )
209  {
210  this->makeNeighbour();
211  }
212 
213  const std::map< int, ParentInformation<DomVecType> > & getInterpolationMap ( ) const
214  {
215  return _interpolationMap;
216  }
217 
219  void mark(int element)
220  {
221  _markedForRefinement[ element ] = true;
222  }
223 
225  void markAll()
226  {
227  for( unsigned i = 0; i < _markedForRefinement.size(); i++ ) _markedForRefinement[i] = true;
228  }
229 
231  void unmark( int element )
232  {
233  _markedForRefinement[ element ] = false;
234  }
235 
237  void unmarkAll()
238  {
239  for( unsigned i = 0; i < _markedForRefinement.size(); i++ )
240  _markedForRefinement[i] = false;
241  }
242  bool isMarkedForRefinement(int element) const
243  {
244  return _markedForRefinement[element];
245  }
246 
248  int pushBackTriang(const Indices3DType newTriang)
249  {
250  _markedForRefinement.push_back( false );
252  }
253 
257  {
258  const int numElements = this->getNumTriangs();
259  for ( int elementIndex = 0; elementIndex < numElements; ++elementIndex )
260  if ( isMarkedForRefinement( elementIndex ) ) refine( elementIndex );
261  this->makeOrientationConsistent();
262  this->updateAllTriangles();
263  }
264 
266  void prolongateLinearly(VectorType& function) const
267  {
268  VectorType oldFunction = function;
269  int oldSize = function.size();
270  function.resize( this->getNumVertices() );
271  for( int i = 0; i < oldSize; ++i ) function[i] = oldFunction[i];
272  typename std::map< int, ParentInformation<DomVecType> >::const_iterator iter;
273  for( int i = oldSize; i < function.size(); ++i ) {
274  iter = _interpolationMap.find( i );
275  if( iter == _interpolationMap.end() ) throw std::invalid_argument ( aol::strprintf ( "unknown vertex in File %s at line %d.", __FILE__, __LINE__ ).c_str() );
276  function[i] = 0.5 * ( function[iter->second.globalIndices[0]] + function[iter->second.globalIndices[1]] );
277  }
278  }
279 
282  {
283  // get global node indices of triangle
284  const Indices3DType &triangIdx ( this->getTriang( triangle ).getGlobalNodeIdx() );
285  // assume that edge 0 is longest edge
286  LocalIndex localIdx = 0;
287  Point3DType edge = this->getVertex( triangIdx[1] );
288  edge -= this->getVertex( triangIdx[2] );
289  RealType maxLength = edge.squaredNorm();
290  // now check if edge 1 is longer
291  edge = this->getVertex( triangIdx[2] );
292  edge -= this->getVertex( triangIdx[0] );
293  RealType candidate = edge.squaredNorm();
294  if( candidate > maxLength ) {
295  localIdx = 1;
296  maxLength = candidate;
297  }
298  // now check if edge 2 is longer
299  edge = this->getVertex( triangIdx[0] );
300  edge -= this->getVertex( triangIdx[1] );
301  candidate = edge.squaredNorm();
302  if( candidate > maxLength ) localIdx = 2;
303 
304  return localIdx;
305  }
306 
307 protected:
308  // internal refinement functions
309  GlobalIndex refine(GlobalIndex triangleToRefine)
310  {
311  DartIterator d( *this, triangleToRefine, getLongestEdgeIndex( triangleToRefine ) );
312  return refine( d );
313  }
314 
316  {
318 
320  return 0;
321  }
322 
326  {
327  DartIterator d1 = d;
328  d1.flipNode();
329 
331  parents.globalIndices[0] = d.getGlobalNodeIndex();
332  parents.globalIndices[1] = d1.getGlobalNodeIndex();
333  parents.ElementIndex = d.getGlobalTriangleIndex();
334 
335  // get edge midpoint between nodes n1 and n2
336  Point3DType newVertex;
337  newVertex.setZero();
338  newVertex += this->getVertex ( d.getGlobalNodeIndex() );
339  newVertex += this->getVertex ( d1.getGlobalNodeIndex() );
340  newVertex /= 2.;
341 
342  // add new vertex
343  int newNodeIdx = this->pushBackVertex( newVertex );
344  _interpolationMap.insert( std::pair< int, ParentInformation<DomVecType> >( newNodeIdx, parents ) );
345  return newNodeIdx;
346  }
347 
348 };
349 
350 
351 } // end namespace
352 
353 #endif
void flipEdge()
moves to other edge with _node (inside current triangle)
GlobalIndex refine(GlobalIndex triangleToRefine)
void flipNode()
Moves to other node along _edge (inside current triangle)
DataTypeContainer::MaskType MaskType
void unmarkAll()
Unmark all elements.
std::map< int, ParentInformation< DomVecType > > _interpolationMap
void refineMarkedTriangles()
Refines at least all triangles that have been marked.
short LocalIndex
defines for local node and edge numbering
void flipTriangle()
Moves to neighbouring triangle across _edge.
void mark(int element)
Mark element for refinement.
int getNeighbour(const int elementID, const int acrossLocalEdge) const
Get neighbor on edge.
Definition: triangMesh.h:76
DataTypeContainer::RealType RealType
std::vector< bool > _markedForRefinement
int pushBackTriang(const Indices3DType newTriang)
bool canFlipTriangle() const
Does _triangle have a neighbour across _edge?
DataTypeContainer::VectorType VectorType
void prolongateLinearly(VectorType &function) const
Prolongate by linear interpolation.
void markAll()
Mark all elements for refinement.
std::vector< Indices3DType > VertexIndicesType
int GlobalIndex
LocalIndex getLongestEdgeIndex(GlobalIndex triangle) const
Get longest edge index (starting search possibly with a preferred edge)
GlobalIndex getCommonNodeGlobalIndex(const DartIteratorType &d) const
Returns global index of common node (also if "d" refers to a different triangle than _triangle ) ...
int getTriangNodeIdx(const int num, const int localNode) const
Definition: triangMesh.h:104
double RealType
Definition: ex2.cpp:21
GlobalIndex addEdgeMidpoint(const DartIterator &d)
Add edge midpoint on d.edge, update _interpolationMap and return global index of node.
string strprintf(const char *format,...)
Give back formatted string, analogously to sprintf, but save the long way &#39;round with char arrays...
Definition: aol.cpp:5
DartIterator(const MeshType &Mesh, GlobalIndex triangleIndex, LocalIndex localEdgeIndex, LocalIndex localNodeIndex)
Constructor.
LocalIndex getCommonNodeLocalIndex(const DartIteratorType &d) const
Returns local index of common node (first checking if "d" also refers to _triangle, but to a different node)
DartIterator(const MeshType &Mesh, GlobalIndex triangleIndex, LocalIndex localEdgeIndex)
Constructor. Does not take a note, but orients the DartIterator counterclockwise. ...
ConfiguratorType::VectorType VectorType
Definition: ex2.cpp:26
std::vector< Point3DType > VertexCoordsType
bool isMarkedForRefinement(int element) const
DataTypeContainer::Point3DType Point3DType
DataTypeContainer::Indices3DType Indices3DType
const int IndexNotSet
void unmark(int element)
Ensure that element is not marked for refinement.
AdaptiveTriangMesh(const string &fileName)
DataTypeContainer::DomVecType DomVecType
Triangle which has a tangent space at each node.
GlobalIndex refine(const DartIterator &d)
const std::map< int, ParentInformation< DomVecType > > & getInterpolationMap() const
AdaptiveTriangMesh< DataTypeContainer, TriangleType > MeshType