Memosa-FVM  0.2
GenericKineticIBDiscretization.h
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 #ifndef _GENERICKINETICIBDISCRETIZATION_H_
6 #define _GENERICKINETICIBDISCRETIZATION_H_
7 
8 #include "CRMatrix.h"
9 #include "Field.h"
10 #include "MultiField.h"
11 #include "MultiFieldMatrix.h"
12 #include "Mesh.h"
13 #include "Discretization.h"
14 #include "StorageSite.h"
15 #include "DiagonalMatrix.h"
16 #include "DiagonalTensor.h"
17 #include "FlowFields.h"
18 #include "GeomFields.h"
19 #include "Vector.h"
20 #include "NumType.h"
21 
22 
23 template <class X, class Diag, class OffDiag>
25 {
26 public:
27 
29 
32  typedef typename CCMatrix::DiagArray DiagArray;
34 
36  typedef Array<X> XArray;
40 
42  const GeomFields& geomFields,
43  Field& varField,
44  const double cx,
45  const double cy,
46  const double cz,
47  MacroFields& macroFields) :
48  Discretization(meshes),
49  _geomFields(geomFields),
50  _varField(varField),
51  _cx(cx),
52  _cy(cy),
53  _cz(cz),
54  _macroFields(macroFields)
55 {}
56 
57  void discretize(const Mesh& mesh, MultiFieldMatrix& matrix,
58  MultiField& xField, MultiField& rField)
59  {
60  const StorageSite& ibFaces = mesh.getIBFaces();
61  if (ibFaces.getCount() == 0)
62  return;
63  VectorT3Array& v = dynamic_cast<VectorT3Array&>(_macroFields.velocity[ibFaces]);
64  const StorageSite& cells = mesh.getCells();
65  const StorageSite& faces = mesh.getFaces();
66 
67  const CRConnectivity& faceCells = mesh.getAllFaceCells();
68 
69  const MultiField::ArrayIndex xIndex(&_varField,&cells);
70  CCMatrix& dRdX = dynamic_cast<CCMatrix&>(matrix.getMatrix(xIndex,xIndex));
71  CCAssembler& assembler = dRdX.getPairWiseAssembler(faceCells);
72  DiagArray& dRdXDiag=dRdX.getDiag();
73 
74  XArray& xcell =
75  dynamic_cast<XArray&> (xField[xIndex]);
76  XArray& varcell =
77  dynamic_cast<XArray&> (_varField[cells]);
78  XArray& rCell = dynamic_cast<XArray&>(rField[xIndex]);
79 
80  const XArray& xib =
81  dynamic_cast<const XArray&>(_varField[mesh.getIBFaces()]);
82 
83  const IntArray& ibType = dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
84 
85  const IntArray& ibFaceIndex = dynamic_cast<const IntArray&>(_geomFields.ibFaceIndex[faces]);
86 
87  const Field& areaMagField = _geomFields.areaMag;
88  const XArray& faceAreaMag = dynamic_cast<const XArray&>(areaMagField[faces]);
89  const Field& areaField = _geomFields.area;
90  const VectorT3Array& faceArea=dynamic_cast<const VectorT3Array&>(areaField[faces]);
91 
92  // used for computing the average value in IBTYPE_BOUNDARY cells.
93  // we can't use the xcell storage during the loop below since a
94  // cell may have more than one ib face and the current value of
95  // x in the cell is required to correctly impose the dirichlet
96  // condition. so we accumulate the boundary cell value and counts
97  // in the following arrays and after all the faces have been
98  // visited, overwrite any boundary cell values with the average of
99  // all the ib faces
100  const int nCells = cells.getCountLevel1();
101  XArray xB(nCells);
102  Array<int> wB(nCells);
103 
104  xB.zero();
105  wB.zero();
106 
107 
108  const int nFaces = faces.getCount();
109  for(int f=0; f<nFaces; f++)
110  {
111  const int c0 = faceCells(f,0);
112  const int c1 = faceCells(f,1);
113 
114  if (((ibType[c0] == Mesh::IBTYPE_FLUID) && (ibType[c1] == Mesh::IBTYPE_BOUNDARY)) ||
115  ((ibType[c1] == Mesh::IBTYPE_FLUID) && (ibType[c0] == Mesh::IBTYPE_BOUNDARY)))
116  {
117  // this is an iBFace, determine which cell is interior and which boundary
118 
119  const int ibFace = ibFaceIndex[f];
120  if (ibFace < 0)
121  throw CException("invalid ib face index");
122  const X& xface = xib[ibFace];
123  const X uwall = v[ibFace][0];
124  const X vwall = v[ibFace][1];
125  const X wwall = v[ibFace][2];
126  if (ibType[c0] == Mesh::IBTYPE_FLUID)
127  {
128  const VectorT3 en = faceArea[f]/faceAreaMag[f];
129  const X c_dot_en = _cx*en[0]+_cy*en[1]+_cz*en[2];
130  const X wallv_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
131  if(c_dot_en - wallv_dot_en <0 ){
132  rCell[c0] += assembler.getCoeff01(f)*(xface-varcell[c1]);
133  rCell[c1] = NumTypeTraits<X>::getZero();
134  assembler.getCoeff01(f) = OffDiag(0);
135  dRdX.setDirichlet(c1);
136  xB[c1] += xface;
137  wB[c1]++;
138  }
139  }
140 
141  else
142  {
143  const VectorT3 en = faceArea[f]/faceAreaMag[f];
144  const X c_dot_en = _cx*en[0]+_cy*en[1]+_cz*en[2];
145  const X wallv_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
146  if(c_dot_en - wallv_dot_en> 0){
147  rCell[c1] += assembler.getCoeff10(f)*(xface-varcell[c0]);
148  rCell[c0] = NumTypeTraits<X>::getZero();
149  assembler.getCoeff10(f) = OffDiag(0);
150  dRdX.setDirichlet(c0);
151  xB[c0] += xface;
152  wB[c0]++;
153  }
154  }
155  }
156  else if ((ibType[c0] == Mesh::IBTYPE_FLUID) &&
157  (ibType[c1] == Mesh::IBTYPE_FLUID))
158  {
159  // leave as is
160  }
161  else
162  {
163  // setup to get zero corrections
164  rCell[c0] = NumTypeTraits<X>::getZero();
165  rCell[c1] = NumTypeTraits<X>::getZero();
170 
171  }
172  }
173 
174  // set the phi for boundary cells as average of the ib face values
175  for(int c=0; c<nCells; c++)
176  {
177  if (wB[c] > 0)
178  varcell[c] = xB[c] / T_Scalar(wB[c]);
179 
180  }
181  }
182 
183 private:
186  const double _cx;
187  const double _cy;
188  const double _cz;
190 };
191 
192 #endif
virtual void zero()
Definition: Array.h:281
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
const StorageSite & getIBFaces() const
Definition: Mesh.h:111
void discretize(const Mesh &mesh, MultiFieldMatrix &matrix, MultiField &xField, MultiField &rField)
Definition: Field.h:14
Definition: Mesh.h:49
GenericKineticIBDiscretization(const MeshList &meshes, const GeomFields &geomFields, Field &varField, const double cx, const double cy, const double cz, MacroFields &macroFields)
OffDiag & getCoeff10(const int np)
Definition: CRMatrix.h:131
Array< Diag > & getDiag()
Definition: CRMatrix.h:856
Field ibType
Definition: GeomFields.h:38
const CRConnectivity & getAllFaceCells() const
Definition: Mesh.cpp:378
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
const StorageSite & getFaces() const
Definition: Mesh.h:108
Field ibFaceIndex
Definition: GeomFields.h:40
const StorageSite & getCells() const
Definition: Mesh.h:109
int getCountLevel1() const
Definition: StorageSite.h:72
OffDiag & getCoeff01(const int np)
Definition: CRMatrix.h:126
Field velocity
Definition: MacroFields.h:15
int getCount() const
Definition: StorageSite.h:39
Field area
Definition: GeomFields.h:23
void setDirichlet(const int nr)
Definition: CRMatrix.h:887
PairWiseAssembler & getPairWiseAssembler(const CRConnectivity &pairs)
Definition: CRMatrix.h:867
Field areaMag
Definition: GeomFields.h:25
vector< Mesh * > MeshList
Definition: Mesh.h:439