Memosa-FVM  0.2
CellMark.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 "CellMark.h"
8 
9 
10 int
11 inCell(const int cellIndex,
12  const VectorT3& point,
13  const CRConnectivity& faceCells,
14  const CRConnectivity& cellFaces,
15  const VectorT3Array& faceArea,
16  const VectorT3Array& faceCentroid)
17 {
18 
19 
20 
21  int faceNumber=cellFaces.getCount(cellIndex);
22  int flag[faceNumber];
23  int throwFlag=0;
24  int sum=0;
25  VectorT3 Af;
26 
27  //const Array<int>& cellFacesRow = cellFaces.getRow();
28  //const Array<int>& cellFacesCol = cellFaces.getCol();
29 
30  //const Array<int>& faceCellsRow = faceCells.getRow();
31  //const Array<int>& faceCellsCol = faceCells.getCol();
32 
33  // cout<<"cell index is"<<cellIndex<<endl;
34 
35  for (int nf=0; nf<faceNumber; nf++){
36  const int f=cellFaces(cellIndex, nf);
37 
38  //first, judge c0 or c1 to define orientation
39  const int c0=faceCells(f,0);
40  //const int c1=faceCells(f,1);
41  if (cellIndex==c0){
42  Af=(-faceArea[f]);
43  }
44  else {
45  Af=(faceArea[f]);
46  }
47 
48  //calculate product
49  VectorT3 ds=point-faceCentroid[f];
50  double product=dot(Af,ds);
51 
52  if(product > 0.0){ flag[nf]=1;}
53  else if (product < 0.0) {flag[nf]=-1;}
54  else {
55  //cout<<cellIndex<<endl;
56  throwFlag = 1;
57  }
58  sum+=flag[nf];
59  }
60  //particle is on face or vertex, throw it away
61  if (throwFlag == 1){
62  return (0);
63  }
64  //particle is in or out of cell
65  else{
66  if (sum==faceNumber){
67  return (1);
68  }
69  else return (-1);
70  }
71 }
72 
73 
74 
75 
76 
77 void markCell( Mesh& mesh, const int nCells, const int nSelfCells,
78  const CRConnectivity& cellParticles, const CRConnectivity& cellCells )
79 {
80 
81  //step 1: Mark the cells with solid particles as solid
82  //and Mark the cells with no solid particles as fluid
83 
84  for(int c=0; c<nCells; c++){
85  const int particleCount = cellParticles.getCount(c);
86  //if no particle in cell, mark as fluid
87  if (particleCount == 0) {
88  mesh.setIBTypeForCell(c,Mesh::IBTYPE_FLUID);
89  }
90  //if has particle in cell, mark as solid
91  else { mesh.setIBTypeForCell(c,Mesh::IBTYPE_SOLID); }
92  }
93  //step2: in solid cells, mark cells with no fluid neighbors as solid
94  //and mark cells with at least one fluid neighbors as IB cells
95 
96  for (int c=0; c<nCells; c++){
97  const int ibType = mesh.getIBTypeForCell(c);
98  int flag;
99  //search all solid cells
100  if(ibType == Mesh::IBTYPE_SOLID){
101  flag=1; //true for solid cells
102  const int ncNumber=cellCells.getCount(c);
103  for(int nc=0; nc<ncNumber; nc++){
104  const int cellIndex=cellCells(c,nc);
105  if(mesh.getIBTypeForCell(cellIndex)==Mesh::IBTYPE_FLUID && cellIndex < nSelfCells){
106  //if(mesh.getIBTypeForCell(cellIndex)==Mesh::IBTYPE_FLUID){
107  flag=0;
108  }
109  }
110  //if solid cell has at least one fluid cell neighbor, mark as IBM type
111  if(flag==0) mesh.setIBTypeForCell(c,Mesh::IBTYPE_BOUNDARY);
112  }
113  }
114 
115 }
116 
117 
118 void reportCellMark (const Mesh& mesh, const int nCells,
119  const VectorT3Array& cellCentroid,
120  const string fileBase)
121 {
122 
123  string fileName=fileBase+"CellMark.dat";
124  char* file;
125  file=&fileName[0];
126  FILE *fp=fopen(file,"w");
127 
128  for(int c=0; c<nCells; c++){
129  int ibType = mesh.getIBTypeForCell(c);
130  fprintf(fp, "%i\t%i\n", c, ibType);
131  }
132  fclose(fp);
133 
134  string fileName1 = fileBase+"FluidCell.dat";
135  string fileName2 = fileBase+"IBMCell.dat";
136  string fileName3 = fileBase+"SolidCell.dat";
137  char* file1;
138  char* file2;
139  char* file3;
140  file1=&fileName1[0];
141  file2=&fileName2[0];
142  file3=&fileName3[0];
143  FILE *fp1, *fp2, *fp3;
144  fp1=fopen(file1,"w");
145  fp2=fopen(file2,"w");
146  fp3=fopen(file3,"w");
147 
148  for(int c=0; c<nCells; c++){
149  int ibType = mesh.getIBTypeForCell(c);
150  if(ibType == Mesh::IBTYPE_FLUID){
151  fprintf(fp1, "%i\t%e\t%e\t%e\n", c, cellCentroid[c][0],cellCentroid[c][1],cellCentroid[c][2]);
152  }
153  else if(ibType==Mesh::IBTYPE_BOUNDARY){
154  fprintf(fp2, "%i\t%e\t%e\t%e\n", c, cellCentroid[c][0],cellCentroid[c][1],cellCentroid[c][2]);
155  }
156  else if(ibType==Mesh::IBTYPE_SOLID){
157  fprintf(fp3, "%i\t%e\t%e\t%e\n", c, cellCentroid[c][0],cellCentroid[c][1],cellCentroid[c][2]);
158  }
159  }
160  fclose(fp1);
161  fclose(fp2);
162  fclose(fp3);
163 }
164 
165 
166 void markIBFaces(Mesh& mesh, const int nFaces,
167  const CRConnectivity& faceCells)
168 {
169  //definition of ibFaces: the faces between IB cells and Fluid cells
170  //first, count the number of ibFaces
171  int ibFaceCount=0;
172  for(int f=0; f<nFaces; f++){
173  const int c0 = faceCells(f, 0);
174  const int c1 = faceCells(f, 1);
175  const int type0 = mesh.getIBTypeForCell(c0);
176  const int type1 = mesh.getIBTypeForCell(c1);
177  if(type0 == Mesh::IBTYPE_FLUID && type1 == Mesh::IBTYPE_BOUNDARY)
178  ibFaceCount++;
179  if(type1 == Mesh::IBTYPE_FLUID && type0 == Mesh::IBTYPE_BOUNDARY)
180  ibFaceCount++;
181  }
182  cout<<"ibFaceCount is "<<ibFaceCount<<endl;
183 
184  //then, allocate an array for ibFace
185  mesh.createIBFaceList(ibFaceCount);
186 
187  //insert the entries to ibface array
188  ibFaceCount=0;
189  for(int f=0; f<nFaces; f++){
190  const int c0 = faceCells(f, 0);
191  const int c1 = faceCells(f, 1);
192  const int type0 = mesh.getIBTypeForCell(c0);
193  const int type1 = mesh.getIBTypeForCell(c1);
194  if(type0 == Mesh::IBTYPE_FLUID && type1 == Mesh::IBTYPE_BOUNDARY){
195  mesh.addIBFace(ibFaceCount, f);
196  ibFaceCount++;
197  }
198  if(type1 == Mesh::IBTYPE_FLUID && type0 == Mesh::IBTYPE_BOUNDARY){
199  mesh.addIBFace(ibFaceCount, f);
200  ibFaceCount++;
201  }
202  }
203 
204 
205  //initialize storagesite ibFaces
206  StorageSite& ibFaces = mesh.getIBFaces();
207  ibFaces.setCount(ibFaceCount);
208 
209 }
210 
211 
212 void checkIBFaces(const Array<int> & ibFaceList,
213  const VectorT3Array& faceArea,
214  const CRConnectivity& faceCells,
215  const Mesh& mesh)
216 {
217 
218  // check if ibFaces form a closed curve //
219 
220  VectorT3 areaSum;
221  areaSum[0] = 0.0;
222  areaSum[1] = 0.0;
223  areaSum[2] = 0.0;
224  for(int i=0; i<ibFaceList.getLength();i++){
225  const int fID = ibFaceList[i];
226  const int C0 = faceCells(fID, 0);
227  const int C1 = faceCells(fID, 1);
228  if(mesh.getIBTypeForCell(C0)==Mesh::IBTYPE_FLUID
229  && mesh.getIBTypeForCell(C1)==Mesh::IBTYPE_SOLID){
230  areaSum += faceArea[fID];
231  }
232  else {
233  areaSum += faceArea[fID];
234  }
235  }
236  cout<<"sum of ibFace area is "<<areaSum<<endl;
237 }
238 
239 
240 
241 
242 const shared_ptr<CRConnectivity> setibFaceParticles
243  (const Mesh& mesh,
244  const StorageSite& ibFaces,
245  const Array<int>& ibFaceList,
246  const StorageSite& particles,
247  const CRConnectivity& faceCells,
248  const CRConnectivity& cellParticles,
249  const CRConnectivity& cellCells,
250  const Array<int>& particleType)
251 {
252 
253  //CR connectivity cellParticles includes all the particles located in each cell
254  //here, we want to create ibFace to Particles in which only the surface particles are counted in
255  //surface particles are identified by particle type 1
256 
257  shared_ptr<CRConnectivity> ibFaceParticles (new CRConnectivity (ibFaces, particles));
258  int maxcount = 0;
259  int mincount = 1000;
260  //initCount: new Array for row
261  (*ibFaceParticles).initCount();
262  const int rowSize = ibFaces.getCount();
263 
264  //specify the number of nonzeros for each row
265 
266  for(int p=0; p<rowSize; p++){
267  const int faceIndex = ibFaceList [p];
268  int C0 = faceCells(faceIndex, 0);
269  int C1 = faceCells(faceIndex, 1);
270 
271  if (mesh.getIBTypeForCell(C1) == Mesh::IBTYPE_BOUNDARY)
272  { C0 = C1; }
273  //C0 is IBtype, C1 is fluid
274 
275  int nP = cellParticles.getCount(C0);
276  int count=0;
277  for(int n=0; n<nP; n++){
278  int pID = cellParticles(C0, n);
279  if(particleType[pID] == 1){
280  count++;
281  }
282  }
283 #if 1
284  //assuming only one fluid cell is used in interpolation, then at least three particles are needed to
285  //apply the linear least square method. If the current IB cell has less than three particles, then search
286  //neighbors for more particles
287  if(count < 3){
288  const int nbSize = cellCells.getCount(C0);
289  for(int c=0; c < nbSize; c++){
290  int cnb = cellCells(C0, c);
291  nP = cellParticles.getCount(cnb);
292  for (int n=0; n<nP; n++){
293  int pID = cellParticles(cnb, n);
294  if(particleType[pID] == 1){
295  count++;
296  }
297  }
298  }
299  }
300 #endif
301 
302  if(count>=maxcount) maxcount=count;
303  if(count<=mincount) mincount=count;
304 
305  (*ibFaceParticles).addCount(p, count);
306 
307  }
308 
309  cout<<"max count of particles in IB Cells is "<<maxcount<<endl;
310  cout<<"min count of particles in IB Cells is "<<mincount<<endl;
311  //finishCount: allocate col array and reset row array
312  //ready to get the entries for nonzeros
313  (*ibFaceParticles).finishCount();
314 
315  //add in the entries for each row
316  for(int p=0; p<rowSize; p++){
317  const int faceIndex = ibFaceList [p];
318  int C0 = faceCells(faceIndex, 0);
319  int C1 = faceCells(faceIndex, 1);
320 
321  if (mesh.getIBTypeForCell(C1) == Mesh::IBTYPE_BOUNDARY)
322  { C0 = C1; }
323  //C0 is IBtype, C1 is fluid
324  int count=0;
325  int nP = cellParticles.getCount(C0);
326  for(int n=0; n<nP; n++){
327  int pID=cellParticles(C0,n);
328  if(particleType[pID] == 1){
329  count++;
330  (*ibFaceParticles).add(p, pID);
331  }
332  }
333 #if 1
334  if(count < 3){
335  const int nbSize = cellCells.getCount(C0);
336  for(int c=0; c < nbSize; c++){
337  int cnb = cellCells(C0, c);
338  nP = cellParticles.getCount(cnb);
339  for (int n=0; n<nP; n++){
340  int pID = cellParticles(cnb, n);
341  if(particleType[pID] == 1){
342  (*ibFaceParticles).add(p, pID);
343  }
344  }
345  }
346  }
347 #endif
348 
349  }
350 
351  (*ibFaceParticles).finishAdd();
352 
353  return(ibFaceParticles);
354 }
355 
356 const shared_ptr<CRConnectivity> setibFaceCells
357  (const Mesh& mesh,
358  const Array<int>& ibFaceList,
359  const StorageSite& ibFaces,
360  const StorageSite& cells,
361  const CRConnectivity& faceCells,
362  const CRConnectivity& cellFaces,
363  const VecD3Array& faceCentroid)
364 {
365 
366  shared_ptr<CRConnectivity> ibFaceCells (new CRConnectivity (ibFaces, cells));
367  int maxcount=0;
368  //initCount: new Array for row
369  (*ibFaceCells).initCount();
370 
371  const int rowSize = ibFaces.getCount();
372 
373 
374  //search level = 1, search only one fluid cell adjacent to IBface
375  //search level = 2, search two levels of fluid cell neighborhood of the ibface
376  const int searchLevel = 2 ;
377 
378  //specify the number of nonzeros for each row
379 
380 
381  for(int p=0; p<rowSize; p++){
382  const int IBfaceIndex = ibFaceList [p];
383  int count=0;
384  //find the fluid cells next to ibface
385 
386  int C0 = faceCells(IBfaceIndex, 0);
387  const int cellType = mesh.getIBTypeForCell(C0);
388  if (cellType != Mesh::IBTYPE_FLUID){
389  C0 = faceCells(IBfaceIndex,1);
390  }
391  count ++;
392  if(searchLevel == 2){
393 
394  const int nf = cellFaces.getCount(C0);
395  for(int f=0; f<nf; f++){
396  const int faceID = cellFaces(C0, f);
397  if (faceID != IBfaceIndex){
398  const int CC0 = faceCells(faceID,0);
399  const int CC1 = faceCells(faceID,1);
400  if(CC0 != C0 && mesh.getIBTypeForCell(CC0) == Mesh::IBTYPE_FLUID){
401  count++;
402  }
403  if(CC1 != C0 && mesh.getIBTypeForCell(CC1) == Mesh::IBTYPE_FLUID){
404  count++;
405  }
406  }
407  }
408  }
409 
410  (*ibFaceCells).addCount(p, count);
411  if (count>=maxcount)
412  maxcount=count;
413  }
414 
415  cout<<"max Cell neibhbors "<<maxcount<<endl;
416 
417  //finishCount: allocate col array and reset row array
418  //ready to get the entries for nonzeros
419  (*ibFaceCells).finishCount();
420 
421  //add in the entries for each row
422  for(int p=0; p<rowSize; p++){
423  const int IBfaceIndex = ibFaceList [p];
424  vector<int> cellIndexList;
425  int C0 = faceCells(IBfaceIndex, 0);
426  const int cellType = mesh.getIBTypeForCell(C0);
427  if (cellType != Mesh::IBTYPE_FLUID){
428  C0 = faceCells(IBfaceIndex,1);
429  }
430  (*ibFaceCells).add(p, C0);
431 
432  if(searchLevel == 2){
433  const int nf = cellFaces.getCount(C0);
434  for(int f=0; f<nf; f++){
435  const int faceID = cellFaces(C0, f);
436  if (faceID != IBfaceIndex){
437  const int CC0 = faceCells(faceID,0);
438  const int CC1 = faceCells(faceID,1);
439  if(CC0 != C0 && mesh.getIBTypeForCell(CC0) == Mesh::IBTYPE_FLUID){
440  (*ibFaceCells).add(p, CC0);
441  }
442  if(CC1 != C0 && mesh.getIBTypeForCell(CC1) == Mesh::IBTYPE_FLUID){
443  (*ibFaceCells).add(p, CC1);;
444  }
445  }
446  }
447  }
448  }
449  (*ibFaceCells).finishAdd();
450 
451  return (ibFaceCells);
452 }
453 
454 
455 const shared_ptr<CRConnectivity> setParticleCells
456  (const StorageSite& rowSite,
457  const StorageSite& colSite,
458  const Array<int> & connectivity)
459 {
460  const int rowSize = rowSite.getCount();
461  // const int colSize = colSite.getCount();
462 
463  shared_ptr<CRConnectivity> rowCol (new CRConnectivity (rowSite, colSite));
464 
465  //initCount: new Array for row
466  (*rowCol).initCount();
467 
468  //specify the number of nonzeros for each row
469  //here, each solid point only has connectivity with one cell
470  //so for each row, it has only one nonzero
471  for(int p=0; p<rowSize; p++){
472  int value = connectivity[p];
473  if (value != -1)
474  (*rowCol).addCount(p, 1);
475  }
476 
477  //finishCount: allocate col array and reset row array
478  //ready to get the entries for nonzeros
479  (*rowCol).finishCount();
480 
481  //add in the entries for each row
482  for(int p=0; p<rowSize; p++){
483  int value = connectivity[p];
484  if (value != -1)
485  (*rowCol).add(p, value);
486  }
487 
488  (*rowCol).finishAdd();
489  return(rowCol);
490 
491 }
void checkIBFaces(const Array< int > &ibFaceList, const VectorT3Array &faceArea, const CRConnectivity &faceCells, const Mesh &mesh)
Definition: CellMark.cpp:212
int getCount(const int i) const
const StorageSite & getIBFaces() const
Definition: Mesh.h:111
Vector< double, 3 > VectorT3
Definition: CellMark.cpp:6
const shared_ptr< CRConnectivity > setParticleCells(const StorageSite &rowSite, const StorageSite &colSite, const Array< int > &connectivity)
Definition: CellMark.cpp:456
Definition: Mesh.h:49
void setCount(const int selfCount, const int nGhost=0)
Definition: StorageSite.h:42
void markCell(Mesh &mesh, const int nCells, const int nSelfCells, const CRConnectivity &cellParticles, const CRConnectivity &cellCells)
Definition: CellMark.cpp:77
void markIBFaces(Mesh &mesh, const int nFaces, const CRConnectivity &faceCells)
Definition: CellMark.cpp:166
Array< Vector< double, 3 > > VectorT3Array
Definition: CellMark.cpp:7
Definition: Array.h:14
int getCount() const
Definition: StorageSite.h:39
int inCell(const int cellIndex, const VectorT3 &point, const CRConnectivity &faceCells, const CRConnectivity &cellFaces, const VectorT3Array &faceArea, const VectorT3Array &faceCentroid)
Definition: CellMark.cpp:11
void reportCellMark(const Mesh &mesh, const int nCells, const VectorT3Array &cellCentroid, const string fileBase)
Definition: CellMark.cpp:118
T dot(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:253
const shared_ptr< CRConnectivity > setibFaceCells(const Mesh &mesh, const Array< int > &ibFaceList, const StorageSite &ibFaces, const StorageSite &cells, const CRConnectivity &faceCells, const CRConnectivity &cellFaces, const VecD3Array &faceCentroid)
Definition: CellMark.cpp:357
const shared_ptr< CRConnectivity > setibFaceParticles(const Mesh &mesh, const StorageSite &ibFaces, const Array< int > &ibFaceList, const StorageSite &particles, const CRConnectivity &faceCells, const CRConnectivity &cellParticles, const CRConnectivity &cellCells, const Array< int > &particleType)
Definition: CellMark.cpp:243
int getLength() const
Definition: Array.h:87