Memosa-FVM  0.2
Cell.cpp
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #include "Cell.h"
6 #include <iostream>
7 #include <math.h>
8 #include <algorithm>
9 #include "CRConnectivity.h"
10 
11 using namespace std;
12 
13 #include "Quad.h"
14 #include "Tri.h"
15 #include "Hex.h"
16 #include "Tet.h"
17 #include "Pyramid.h"
18 #include "Prism.h"
19 
20 unsigned int Quad::faceNodeCount[4] = {2,2,2,2};
21 unsigned int Quad::faceNodes[4][2] = { {0,1}, {1,2}, {2,3}, {3, 0}};
22 
23 unsigned int Tri::faceNodeCount[3] = {2,2,2};
24 unsigned int Tri::faceNodes[3][2] = { {0,1}, {1,2}, {2,0}};
25 
26 unsigned int Hex::faceNodeCount[6] = {4,4,4,4,4,4};
27 unsigned int Hex::faceNodes[6][4] = { {0,1,2,3},
28  {4,7,6,5},
29  {0,4,5,1},
30  {1,5,6,2},
31  {2,6,7,3},
32  {3,7,4,0}};
33 
34 unsigned int Tet::faceNodeCount[4] = {3,3,3,3};
35 unsigned int Tet::faceNodes[4][3] = { {0,1,2}, {0,3,1}, {1,3,2}, {2,3,0}};
36 
37 unsigned int Pyramid::faceNodeCount[5] = {4,3,3,3,3};
38 unsigned int Pyramid::faceNodes[5][4] = { {0,1,2,3},
39  {0,4,1,0},
40  {1,4,2,0},
41  {2,4,3,0},
42  {3,4,0,0}};
43 
44 unsigned int Prism::faceNodeCount[5] = {3,3,4,4,4};
45 unsigned int Prism::faceNodes[5][4] = { {0,1,2,0},
46  {3,5,4,0},
47  {0,3,4,1},
48  {1,4,5,2},
49  {2,5,3,0}};
50 
51 template<class CellTrait>
53 {
54  for(int n=0; n<numNodes; n++) _nodeFirstFaceSig[n] = 0;
55 
56  for(int f=0; f<numFaces; f++)
57  {
58  _faceAllNodesSig[f] = 0;
59  for(unsigned int nf=0; nf<CellTrait::faceNodeCount[f]; nf++)
60  {
61  unsigned int n = CellTrait::faceNodes[f][nf];
62  _faceAllNodesSig[f] |= (1<<n);
63  if (f == 0)
64  _nodeFirstFaceSig[n] = 1<<n;
65  }
66  }
67 
68  for(int f=0; f<numFaces; f++)
69  {
70  _faceFirstFaceNodesSig[f] = 0;
71  for(unsigned int nf=0; nf<CellTrait::faceNodeCount[f]; nf++)
72  {
73  unsigned int n = CellTrait::faceNodes[f][nf];
74  _faceFirstFaceNodesSig[f] |= _nodeFirstFaceSig[n];
75  }
76  _faceFirstFaceNodesSigMap[_faceFirstFaceNodesSig[f]] = f;
77  }
78 
79 #if 0
80  for(int f=0; f<numFaces; f++)
81  cout << _faceAllNodesSig[f] << " ";
82  cout << endl;
83 
84  for(int n=0; n<numNodes; n++)
85  cout << _nodeFirstFaceSig[n] << " " ;
86  cout << endl;
87 
88  for(int f=0; f<numFaces; f++)
89  cout << _faceFirstFaceNodesSig[f] << " " ;
90  cout << endl;
91 #endif
92 }
93 
94 
95 template<class CellTrait>
96 void
98  CRConnectivity& cellFaces,
99  CRConnectivity& cellNodes,
100  const CRConnectivity& faceNodes,
101  const CRConnectivity& faceCells,
102  const Array<Vector<double,3> >& nodeCoordinates)
103 {
104 
105  int face0 = 0;
106  int face0NodeCount=0;
107  bool reverseFace0Nodes = false;
108 
109  for(int nf=0; nf<numFaces; nf++)
110  {
111  const int f = cellFaces(c,nf);
112  if ((unsigned int)faceNodes.getCount(f) == CellTrait::faceNodeCount[0])
113  {
114  face0 = f;
115  face0NodeCount = faceNodes.getCount(f);
116  if (faceCells(f,0) != c)
117  {
118  if (faceCells(f,1) != c)
119  cerr << "malformed grid " << endl;
120  reverseFace0Nodes = true;
121  }
122  break;
123  }
124  }
125 
126  map<int, unsigned int> thisNodesFirstFaceNodesSig;
127 
128  for(unsigned int nn=0; nn<(unsigned int)face0NodeCount; nn++)
129  {
130  int node = faceNodes(face0,nn);
131  if (reverseFace0Nodes) node = faceNodes(face0,face0NodeCount-nn-1);
132  thisNodesFirstFaceNodesSig[node] = 1<<nn;
133  }
134 
135  int orderedFaces[numFaces];
136 
137  for(int nf=0; nf<numFaces; nf++)
138  {
139  unsigned int thisFaceFirstFaceNodesSig = 0;
140  const int f = cellFaces(c,nf);
141 
142  for(int nn=0; nn<faceNodes.getCount(f); nn++)
143  {
144  const int n = faceNodes(f,nn);
145 
146  if (thisNodesFirstFaceNodesSig.find(n) !=
147  thisNodesFirstFaceNodesSig.end())
148  thisFaceFirstFaceNodesSig |= thisNodesFirstFaceNodesSig[n];
149  }
150 
151  int faceOrder = _faceFirstFaceNodesSigMap[thisFaceFirstFaceNodesSig];
152  orderedFaces[faceOrder] = f;
153  }
154 
155  for(int nf=0; nf<numFaces; nf++)
156  cellFaces(c,nf) = orderedFaces[nf];
157 
158 
159  map<int, unsigned int> thisNodesAllFaceNodesSig;
160 
161  for(int nf=0; nf<numFaces; nf++)
162  {
163  // unsigned int thisFaceFirstFaceNodeSig = 0;
164  const int f = cellFaces(c,nf);
165 
166  // bool reverseFaceNodes = (faceCells(f,0) != c);
167 
168  const int faceNodeCount = faceNodes.getCount(f);
169  for(int nn=0; nn<faceNodeCount; nn++)
170  {
171  int n = faceNodes(f,nn);
172  if (reverseFace0Nodes) n = faceNodes(f,faceNodeCount-nn-1);
173 
174  if (thisNodesAllFaceNodesSig.find(n) ==
175  thisNodesAllFaceNodesSig.end())
176  {
177  thisNodesAllFaceNodesSig[n] =
178  _faceAllNodesSig[nf];
179  }
180  else
181  {
182  thisNodesAllFaceNodesSig[n] &=
183  _faceAllNodesSig[nf];
184  }
185  }
186  }
187 
188  for( map<int,unsigned int>::const_iterator pos =
189  thisNodesAllFaceNodesSig.begin();
190  pos != thisNodesAllFaceNodesSig.end();
191  ++pos)
192  {
193  const int node = pos->first;
194  // log2 missing in msvc ?
195  const int index = (int) log2(pos->second);
196  // const int index = (int) (log( (double) pos->second)/log(2.));
197  cellNodes(c,index) = node;
198  }
199 
200 }
201 
202 template class Cell<Quad>;
203 template class Cell<Tri>;
204 template class Cell<Hex>;
205 template class Cell<Tet>;
206 template class Cell<Pyramid>;
207 template class Cell<Prism>;
208 
209 
211 static Cell<Tri> tri;
216 
217 #include "StorageSite.h"
218 
219 struct MyCoords
220 {
221  MyCoords(int i_, const double x_) :
222  i(i_),
223  x(x_)
224  {}
225 
226  MyCoords(const MyCoords& o) :
227  i(o.i),
228  x(o.x)
229  {}
230 
231  int i;
232  double x;
233 };
234 
235 bool myCoordComparison (const MyCoords& a, const MyCoords& b)
236 {
237  return (a.x<b.x);
238 }
239 
240 void
242  CRConnectivity& cellNodes,
243  const CRConnectivity& faceNodes,
244  const CRConnectivity& faceCells,
245  const Array<Vector<double,3> >& nodeCoordinates)
246 {
247 
248  const int numCells = cellNodes.getRowSite().getSelfCount();
249 
250  for(int c=0; c<numCells; c++)
251  {
252  const int numCellNodes = cellNodes.getCount(c);
253  const int numCellFaces = cellFaces.getCount(c);
254 
255  int edgeFaceCount =0;
256  int triFaceCount = 0;
257  int quadFaceCount = 0;
258  for(int nf=0; nf<numCellFaces; nf++)
259  {
260  const int f = cellFaces(c,nf);
261  const int faceNodeCount = faceNodes.getCount(f);
262  switch(faceNodeCount)
263  {
264  case 2:
265  edgeFaceCount++;
266  break;
267  case 3:
268  triFaceCount++;
269  break;
270  case 4:
271  quadFaceCount++;
272  break;
273  default:
274  break;
275  }
276  }
277 
278  if (numCellNodes == 4 && edgeFaceCount == 4)
279  {
280  quad.orderCellFacesAndNodes(c,cellFaces,cellNodes,
281  faceNodes,faceCells,nodeCoordinates);
282  }
283  else if (numCellNodes == 3 && edgeFaceCount == 3)
284  {
285  tri.orderCellFacesAndNodes(c,cellFaces,cellNodes,
286  faceNodes,faceCells,nodeCoordinates);
287  }
288  else if (numCellNodes == edgeFaceCount)
289  {
290  vector<MyCoords> angles;
292  for(int nn=0; nn<numCellNodes; nn++)
293  mean += nodeCoordinates[cellNodes(c,nn)];
294  mean /= numCellNodes;
295  for(int nn=0; nn<numCellNodes; nn++)
296  {
297  const int nodeIndex = cellNodes(c,nn);
298  const Vector<double,3> xm =
299  nodeCoordinates[nodeIndex] - mean;
300  const double angle = atan2(xm[1], xm[0]);
301  angles.push_back(MyCoords(nodeIndex,angle));
302  }
303 
304  sort(angles.begin(),angles.end(),myCoordComparison);
305 
306  for(int nn=0; nn<numCellNodes; nn++)
307  {
308  cellNodes(c,nn) = angles[nn].i;
309  }
310  }
311  else if (numCellNodes == 8 && quadFaceCount == 6)
312  {
313  hexCell.orderCellFacesAndNodes(c,cellFaces,cellNodes,
314  faceNodes,faceCells,nodeCoordinates);
315  }
316  else if (numCellNodes == 4 && triFaceCount == 4)
317  {
318  tetCell.orderCellFacesAndNodes(c,cellFaces,cellNodes,
319  faceNodes,faceCells,nodeCoordinates);
320  }
321  else if (numCellNodes == 5 && triFaceCount == 4 &&
322  quadFaceCount == 1)
323  {
324  pyramidCell.orderCellFacesAndNodes(c,cellFaces,cellNodes,
325  faceNodes,faceCells,
326  nodeCoordinates);
327  }
328  else if (numCellNodes == 6 && triFaceCount == 2 &&
329  quadFaceCount == 3)
330  {
331  prismCell.orderCellFacesAndNodes(c,cellFaces,cellNodes,
332  faceNodes,faceCells,
333  nodeCoordinates);
334  }
335  else
336  {
337 #if 0
338  cerr << "unimplemented cell type: numCellnodes = "
339  << numCellNodes
340  << " quadFaceCount = " << quadFaceCount
341  << " triFaceCount = " << triFaceCount
342  << " edgeFaceCount = " << edgeFaceCount
343  << endl;
344 #endif
345  }
346  }
347 }
348 
static unsigned int faceNodes[numFaces][3]
Definition: Tet.h:18
int getCount(const int i) const
void orderCellFacesAndNodes(const int c, CRConnectivity &cellFaces, CRConnectivity &cellNodes, const CRConnectivity &faceNodes, const CRConnectivity &faceCells, const Array< Vector< double, 3 > > &nodeCoordinates)
Definition: Cell.cpp:97
int getSelfCount() const
Definition: StorageSite.h:40
Definition: Cell.h:16
static Cell< Quad > quad
Definition: Cell.cpp:210
static unsigned int faceNodeCount[numFaces]
Definition: Tri.h:17
static Cell< Pyramid > pyramidCell
Definition: Cell.cpp:214
MyCoords(const MyCoords &o)
Definition: Cell.cpp:226
static Cell< Tri > tri
Definition: Cell.cpp:211
static Cell< Tet > tetCell
Definition: Cell.cpp:213
static Cell< Prism > prismCell
Definition: Cell.cpp:215
void orderCellFacesAndNodes(CRConnectivity &cellFaces, CRConnectivity &cellNodes, const CRConnectivity &faceNodes, const CRConnectivity &faceCells, const Array< Vector< double, 3 > > &nodeCoordinates)
Definition: Cell.cpp:241
static unsigned int faceNodes[numFaces][2]
Definition: Quad.h:20
bool myCoordComparison(const MyCoords &a, const MyCoords &b)
Definition: Cell.cpp:235
static unsigned int faceNodeCount[numFaces]
Definition: Prism.h:17
static unsigned int faceNodes[numFaces][4]
Definition: Hex.h:18
Cell()
Definition: Cell.cpp:52
static Cell< Hex > hexCell
Definition: Cell.cpp:212
static unsigned int faceNodeCount[numFaces]
Definition: Quad.h:19
Definition: Array.h:14
static unsigned int faceNodes[numFaces][4]
Definition: Prism.h:18
static unsigned int faceNodes[numFaces][4]
Definition: Pyramid.h:18
static unsigned int faceNodes[numFaces][2]
Definition: Tri.h:18
static unsigned int faceNodeCount[numFaces]
Definition: Pyramid.h:17
static unsigned int faceNodeCount[numFaces]
Definition: Tet.h:17
static unsigned int faceNodeCount[numFaces]
Definition: Hex.h:17
MyCoords(int i_, const double x_)
Definition: Cell.cpp:221
const StorageSite & getRowSite() const
int i
Definition: Cell.cpp:231
double x
Definition: Cell.cpp:232