Memosa-FVM  0.2
Grid.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 "Grid.h"
6 
8 
10 
11 shared_ptr<Array<VecD3> >
12 readVectors(const char *file)
13 {
14  FILE *fp;
15  int nGrid;
16  double vx=0, vy=0, vz=0;
17 
18  fp=fopen(file,"r");
19  fscanf(fp,"%i\n",&nGrid);
20  shared_ptr<Array<VecD3> > Grid_Points (new Array<VecD3> (nGrid));
21 
22  //read in velocity
23  for(int i=0; i<nGrid; i++){
24  fscanf(fp,"%lf\t%lf\t%lf\n", &vx, &vy, &vz);
25  (*Grid_Points)[i][0]=vx;
26  (*Grid_Points)[i][1]=vy;
27  (*Grid_Points)[i][2]=vz;
28  }
29  fclose(fp);
30  return (Grid_Points);
31 }
32 
33 Grid::Grid(GeomFields& geomFields, FlowFields& flowFields, string coordFileName,
34  string velocityFileName):
35  _geomFields(geomFields),
36  _flowFields(flowFields),
37  _nodes(0),
38  _cells(0),
39  _coordinates(),
40  _velocities()
41 {
42 
43  //set up grid data//
44  //grid.setandwriteGrids(fileBase);
45 
46  //read grid coordinates
47 
48  _coordinates = readVectors(coordFileName.c_str());
49 
50  //read grid velocity
51  _velocities = readVectors(velocityFileName.c_str());
52 
53  _nodes.setCount(_velocities->getLength());
54 
55  //store coordinates in geomField
57 
58  //store velocity in flowField
59  flowFields.velocity.addArray(_nodes, _velocities);
60 
61  // create cell to node connectivity
63 
64 #if 0
65  //test findCells using single point
66  VecD3 point;
67  point[0]=0.;
68  point[1]=0.6;
69  point[2]=0.0;
70  const StorageSite& gridCells = grid.getCells();
71 
72  const int nGridCells = gridCells.getCount();
73 
74  const CRConnectivity& cellToGrids = mesh.getConnectivity(gridCells, grids);
75 
76  vector<int> nb = findNeighborsByCells(point, (*Grid_Coordinates), nGridCells, cellToGrids);
77  for(int n=0; n<nb.size();n++){
78  cout<<"point is in cell "<<nb[n]<<endl;
79  }
80 #endif
81 }
82 
84 
85 void Grid::setandwriteGrids(const string fileBase)
86 {
87 
88  int nX=7, nY=3, nZ=1;
89  double gapX=1.4/nX, gapY=1.2/nY, gapZ=0.0/nZ;
90 
91  VecD3 center;
92  center[0]=0.501;
93  center[1]=0.501;
94  center[2]=0.0;
95 
96  int count=0;
97  VecD3 gridCoord[nX*nY*nZ];
98  VecD3 gridVelocity[nX*nY*nZ];
99 
100  //set up grid coordinate
101  for(int i=0; i<nX; i++){
102  for(int j=0; j<nY; j++){
103  for(int k=0; k<nZ; k++){
104  gridCoord[count][0]=i*gapX-0.023;//+(center[0]-(nX*gapX/2.));
105  gridCoord[count][1]=-j*gapY+0.92;//+(center[1]-(nY*gapY/2.));
106  gridCoord[count][2]=k*gapZ;
107  count+=1;
108  }
109  }
110  }
111 
112  //set up grid velocity
113  const double vMax=1.0;
114  const double vMin=0.0;
115  const double vGap=(vMax-vMin)/nX;
116  count=0;
117  for(int i=0; i<nX; i++){
118  for(int j=0; j<nY; j++){
119  for(int k=0; k<nZ; k++){
120  gridVelocity[count][0]=vMin+vGap*i;
121  gridVelocity[count][1]=0.0;
122  gridVelocity[count][2]=0.0;
123  count++;
124  }
125  }
126  }
127  //write out coordinate into file
128  string fileName1=fileBase+"Grid_Coord.dat";
129  char* file1;
130  file1=&fileName1[0];
131  FILE *fp1=fopen(file1,"w");
132  fprintf(fp1,"%i\n",count);
133  for(int p=0; p<count; p++){
134  fprintf(fp1, "%lf\t%lf\t%lf\n", gridCoord[p][0], gridCoord[p][1], gridCoord[p][2]);
135  }
136  fclose(fp1);
137 
138  //write out velocity into file
139  string fileName2=fileBase+"Grid_Velocity.dat";
140  char* file2;
141  file2=&fileName2[0];
142  FILE *fp2=fopen(file2,"w");
143  fprintf(fp2,"%i\n",count);
144  for(int p=0; p<count; p++){
145  fprintf(fp2, "%lf\t%lf\t%lf\n", gridVelocity[p][0],gridVelocity[p][1],gridVelocity[p][2]);
146  }
147  fclose(fp2);
148 }
149 
150 
152 {
153  const int nXGrid = 7;
154  const int nYGrid = 3;
155 
156  //init storagesite for cells
157  const int nGridCells = (nXGrid-1)*(nYGrid-1)*2;
158  _cells.setCount(nGridCells);
159 
160  //create cell to grids connectivity
161  //since it is tri cell, each cell connects to 3 grid points
162  _cellNodes = shared_ptr<CRConnectivity>(new CRConnectivity (_cells, _nodes));
163  (*_cellNodes).initCount();
164  for (int n=0; n<nGridCells; n++){
165  (*_cellNodes).addCount(n, 3);
166  }
167  (*_cellNodes).finishCount();
168  int node1, node2, node3;
169  int id = 0;
170  for (int n=0; n<nGridCells/2; n+=2){
171  node1 = id;
172  node2 = id+1;
173  node3 = id+4;
174  (*_cellNodes).add(n, node1);
175  (*_cellNodes).add(n, node2);
176  (*_cellNodes).add(n, node3);
177  node1 = id;
178  node2 = id+4;
179  node3 = id+3;
180  (*_cellNodes).add(n+1, node1);
181  (*_cellNodes).add(n+1, node2);
182  (*_cellNodes).add(n+1, node3);
183  id+=3;
184  }
185  id = 1;
186  for (int n=nGridCells/2; n<nGridCells; n+=2){
187  node1 = id;
188  node2 = id+1;
189  node3 = id+4;
190  (*_cellNodes).add(n, node1);
191  (*_cellNodes).add(n, node2);
192  (*_cellNodes).add(n, node3);
193  node1 = id;
194  node2 = id+4;
195  node3 = id+3;
196  (*_cellNodes).add(n+1, node1);
197  (*_cellNodes).add(n+1, node2);
198  (*_cellNodes).add(n+1, node3);
199  id+=3;
200  }
201 
202  (*_cellNodes).finishAdd();
203 
204 }
205 
206 //giving a point, find out which cell contains this point
207 //since the number of cells is not large, we search by loop over all cells
208 vector<int>
210 {
211  vector<int> neighborList;
212  const int nCells = _cells.getCount();
213  const CRConnectivity& cellNodes = *_cellNodes;
214  const Array<VecD3>& nodeCoords = *_coordinates;
215 
216  for ( int c=0; c<nCells; c++){
217  const int nsize = cellNodes.getCount(c);
218  int node[nsize];
219  for(int n=0; n<nsize; n++){
220  node[n] = cellNodes(c,n);
221  }
222  Array<VecD3> faceArea(nsize);
223  Array<VecD3> faceCentroid(nsize);
224  for(int n=0; n<nsize-1; n++){
225  faceArea[n]=nodeCoords[node[n+1]]-nodeCoords[node[n]];
226  faceCentroid[n]=(nodeCoords[node[n+1]]+nodeCoords[node[n]])/2.;
227  }
228  faceArea[nsize-1]=nodeCoords[node[0]]-nodeCoords[node[nsize-1]];
229  faceCentroid[nsize-1]=(nodeCoords[node[0]]+nodeCoords[node[nsize-1]])/2.;
230 
231  int find = 1;
232  for(int n=0; n<nsize; n++){
233  VecD3 faceNorm;
234  faceNorm[0]=faceArea[n][1];
235  faceNorm[1]=-faceArea[n][0];
236  faceNorm[2]=faceArea[n][2];
237 
238  VecD3 dr = point - faceCentroid[n];
239  dr[2] = 0.0; //difference in z direction is neglected. just check x-y plane
240  if (dot(faceNorm,dr) > 0.0) {
241  find = 0;
242  break;
243  }
244  }
245  //point falls into a cell
246  if (find){
247  for(int n=0; n<nsize; n++){
248  node[n]=cellNodes(c,n);
249  neighborList.push_back(node[n]);
250  }
251  return(neighborList);
252  }
253  }
254 
255  //point falls outside of grid boundary
256  //find the cloest cell to this point
257  //use that cell to interpolate
258 
259  double distMin = 1.0e10;
260  int closestCell = 0;
261  for ( int c=0; c<nCells; c++){
262  const int nsize = cellNodes.getCount(c);
263  VecD3 cellCentroid;
264  cellCentroid[0]=0.0;
265  cellCentroid[1]=0.0;
266  cellCentroid[2]=0.0;
267  for(int n=0; n<nsize; n++){
268  cellCentroid += nodeCoords[cellNodes(c,n)];
269  }
270  cellCentroid /= 3.;
271  VecD3 dr = point - cellCentroid;
272  double distance = mag(dr);
273  if(distance < distMin){
274  distMin = distance;
275  closestCell = c;
276  }
277  }
278  const int nsize = cellNodes.getCount(closestCell);
279  for(int n=0; n<nsize; n++){
280  neighborList.push_back(cellNodes(closestCell,n));
281  }
282  return(neighborList);
283 }
284 
285 
286 
287 
288 //giving a point, find out its neighboring nodes
290 vector<int>
292 
293 {
294  const Array<VecD3>& nodeCoords = *_coordinates;
295  const int nNodes = nodeCoords.getLength();
296 
297  vector<int> neighborList;
298 
299  //first, judge if this point falls into nodeCoords
300  //if not, return NULL vector
301  //if yes, continue to find the neighbors
302  Vector<int,3> mFlag, pFlag;
303  mFlag=pFlag=0;
304 
305  for (int i=0; i<nNodes; i++){
306  for(int k=0; k<3; k++){
307  if(point[k]<nodeCoords[i][k]) {
308  mFlag[k]++;
309  }
310  if (point[k]>nodeCoords[i][k]) {
311  pFlag[k]++;
312  }
313  }
314  }
315 
316 
317  if(mFlag[0]==nNodes||mFlag[1]==nNodes||mFlag[2]==nNodes||pFlag[0]==nNodes||pFlag[1]==nNodes||pFlag[2]==nNodes)
318  return (neighborList);
319 
320  else{
321 
322  VecD3 pLimit, mLimit, allow, dR;
323  for(int k=0; k<3; k++){
324  pLimit[k]=1e10;
325  mLimit[k]=-1e10;
326  allow[k]=1.e-8;
327  dR[k]=0.0;
328  }
329  //find the bounds for point
330  for(int i=0; i<nNodes; i++){
331  dR = point - nodeCoords[i];
332  for(int k=0; k<3; k++){
333  if( dR[k]<=0.0 && dR[k]>mLimit[k] ){
334  mLimit[k]=dR[k];
335  }
336  if (dR[k]>=0.0 && dR[k]<pLimit[k]){
337  pLimit[k]=dR[k];
338  }
339  }
340  }
341 
342  //find who bounds the point
343 
344  for(int i=0; i<nNodes; i++){
345  if(nodeCoords[i][0]>(point[0]-pLimit[0]-allow[0])&& nodeCoords[i][0]<(point[0]-mLimit[0]+allow[0])){
346  if(nodeCoords[i][1]>(point[1]-pLimit[1]-allow[1])&& nodeCoords[i][1]<(point[1]-mLimit[1]+allow[1])){
347  if(nodeCoords[i][2]>(point[2]-pLimit[2]-allow[2])&& nodeCoords[i][2]<(point[2]-mLimit[2]+allow[2])){
348  neighborList.push_back(i);
349  }
350  }
351  }
352  }
353 
354  return(neighborList);
355  }
356 
357 }
358 
359 
360 //set up pointToNodes connectivity
361 
362 const shared_ptr<CRConnectivity>
364  const VecD3Array& points)
365 {
366  shared_ptr<CRConnectivity> pointToNodes (new CRConnectivity (pointSite, _nodes));
367 
368  (*pointToNodes).initCount();
369 
370  const int nPoints = pointSite.getCount();
371 
372  for(int i=0; i<nPoints; i++){
373 
374  vector<int> neighborList = findNeighborsByCells(points[i]);
375  int count = neighborList.size();
376  if(count!=0)
377  (*pointToNodes).addCount(i, count);
378  }
379 
380  (*pointToNodes).finishCount();
381 
382  for(int i=0; i<nPoints; i++){
383  vector<int> neighborList = findNeighborsByCells(points[i]);
384  int count = neighborList.size();
385  for(int j=0; j<count; j++){
386  (*pointToNodes).add(i, neighborList[j]);
387  }
388  }
389  (*pointToNodes).finishAdd();
390 
391  return(pointToNodes);
392 
393 }
394 
395 
396 
398  const StorageSite& faces)
399 {
400  const VecD3Array& faceCentroid =
401  dynamic_cast<const VecD3Array& > (_geomFields.coordinate[faces]);
402 
403  shared_ptr<CRConnectivity> faceGridsCR =
404  createConnectivity(faces, faceCentroid);
405 
406  mesh.setConnectivity(faces, _nodes, faceGridsCR);
407 }
408 
409 
410 shared_ptr<ArrayBase>
412 {
414  typedef CRMatrixTranspose<double,VecD3,VecD3> IMatrixV3;
415 
416 
417  const int nFaces = faces.getCount();
418 
419 
420  GeomFields::SSPair key(&faces,&_nodes);
421  const IMatrix& mIC =
422  dynamic_cast<const IMatrix&> (*(_geomFields._interpolationMatrices[key]));
423 
424  IMatrixV3 mICV(mIC);
425 
426  shared_ptr<VecD3Array> faceV(new VecD3Array(nFaces));
427 
428  faceV->zero();
429 
430  mICV.multiplyAndAdd(*faceV,*_velocities);
431 
432  return (faceV);
433 
434 }
435 
436 
437 
438 
Array< VecD3 > VecD3Array
Definition: Grid.cpp:9
int getCount(const int i) const
GeomFields & _geomFields
Definition: Grid.h:60
void setandwriteGrids(const string fileBase)
Definition: Grid.cpp:85
StorageSite _cells
Definition: Grid.h:63
Field coordinate
Definition: GeomFields.h:19
shared_ptr< Array< VecD3 > > readVectors(const char *file)
Definition: Grid.cpp:12
shared_ptr< ArrayBase > computeInterpolatedVelocity(const StorageSite &faces)
Definition: Grid.cpp:411
Definition: Mesh.h:49
T mag(const Vector< T, 3 > &a)
Definition: Vector.h:260
Grid(GeomFields &geomFields, FlowFields &flowFields, string coordFileName, string velocityFileName)
Definition: Grid.cpp:33
void setCount(const int selfCount, const int nGhost=0)
Definition: StorageSite.h:42
void setConnectivity(const StorageSite &rowSite, const StorageSite &colSite, shared_ptr< CRConnectivity > conn)
Definition: Mesh.cpp:352
vector< int > findNeighbors(const VecD3 &point)
!! only applicable for rectangular mesh
Definition: Grid.cpp:291
Vector< double, 3 > VecD3
Definition: Grid.cpp:7
vector< int > findNeighborsByCells(const VecD3 &point)
Definition: Grid.cpp:209
map< SSPair, shared_ptr< Matrix > > _interpolationMatrices
Definition: GeomFields.h:50
StorageSite _nodes
Definition: Grid.h:62
shared_ptr< Array< VecD3 > > _coordinates
Definition: Grid.h:64
shared_ptr< CRConnectivity > _cellNodes
Definition: Grid.h:66
const shared_ptr< CRConnectivity > createConnectivity(const StorageSite &pointSite, const VecD3Array &points)
Definition: Grid.cpp:363
void addArray(const StorageSite &, shared_ptr< ArrayBase > a)
Definition: Field.cpp:72
shared_ptr< Array< VecD3 > > _velocities
Definition: Grid.h:65
Definition: Array.h:14
void setConnFaceToGrid(Mesh &mesh, const StorageSite &faces)
Definition: Grid.cpp:397
void createCellToNodeConnectivity()
Definition: Grid.cpp:151
int getCount() const
Definition: StorageSite.h:39
T dot(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:253
pair< const StorageSite *, const StorageSite * > SSPair
Definition: GeomFields.h:48
~Grid()
Definition: Grid.cpp:83
Field velocity
Definition: FlowFields.h:15
int getLength() const
Definition: Array.h:87