Memosa-FVM  0.2
GenericIBDiscretization.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 _GENERICIBDISCRETIZATION_H_
6 #define _GENERICIBDISCRETIZATION_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& phiField) :
44  Discretization(meshes),
45  _geomFields(geomFields),
46  _phiField(phiField)
47 {}
48 
49  void discretize(const Mesh& mesh, MultiFieldMatrix& mfmatrix,
50  MultiField& xField, MultiField& rField)
51  {
52  const StorageSite& ibFaces = mesh.getIBFaces();
53 
54  if (ibFaces.getCount() == 0)
55  return;
56 
57  const StorageSite& cells = mesh.getCells();
58  const StorageSite& faces = mesh.getFaces();
59 
60  const CRConnectivity& faceCells = mesh.getAllFaceCells();
61 
62  const MultiField::ArrayIndex vIndex(&_phiField,&cells);
63  CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(vIndex,vIndex));
64  CCAssembler& assembler = matrix.getPairWiseAssembler(faceCells);
65 
66  XArray& cellPhi =
67  dynamic_cast<XArray&> (_phiField[cells]);
68 
69  XArray& rCell = dynamic_cast<XArray&>(rField[vIndex]);
70 
71  const XArray& ibPhi =
72  dynamic_cast<const XArray&>(_phiField[mesh.getIBFaces()]);
73 
74  const IntArray& ibType = dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
75 
76  const IntArray& ibFaceIndex = dynamic_cast<const IntArray&>(_geomFields.ibFaceIndex[faces]);
77 
78 
79  // used for computing the average value in IBTYPE_BOUNDARY cells.
80  // we can't use the cellPhi storage during the loop below since a
81  // cell may have more than one ib face and the current value of
82  // phi in the cell is required to correctly impose the dirichlet
83  // condition. so we accumulate the boundary cell value and counts
84  // in the following arrays and after all the faces have been
85  // visited, overwrite any boundary cell values with the average of
86  // all the ib faces
87  const int nCells = cells.getCount();
88  XArray xB(nCells);
89  Array<int> wB(nCells);
90 
91  xB.zero();
92  wB.zero();
93 
94 
95  const int nFaces = faces.getCount();
96  for(int f=0; f<nFaces; f++)
97  {
98  const int c0 = faceCells(f,0);
99  const int c1 = faceCells(f,1);
100 
101  if (((ibType[c0] == Mesh::IBTYPE_FLUID) && (ibType[c1] == Mesh::IBTYPE_BOUNDARY)) ||
102  ((ibType[c1] == Mesh::IBTYPE_FLUID) && (ibType[c0] == Mesh::IBTYPE_BOUNDARY)))
103  {
104  // this is an iBFace, determine which cell is interior and which boundary
105 
106  const int ibFace = ibFaceIndex[f];
107  if (ibFace < 0)
108  throw CException("invalid ib face index");
109 
110  const X& facePhi = ibPhi[ibFace];
111  if (ibType[c0] == Mesh::IBTYPE_FLUID)
112  {
113  rCell[c0] += assembler.getCoeff01(f)*(facePhi-cellPhi[c1]);
114  rCell[c1] = NumTypeTraits<X>::getZero();
115  assembler.getCoeff01(f) = OffDiag(0);
116  matrix.setDirichlet(c1);
117  xB[c1] += facePhi;
118  wB[c1]++;
119  }
120  else
121  {
122  rCell[c1] += assembler.getCoeff10(f)*(facePhi-cellPhi[c0]);
123  rCell[c0] = NumTypeTraits<X>::getZero();
124  assembler.getCoeff10(f) = OffDiag(0);
125  matrix.setDirichlet(c0);
126  xB[c0] += facePhi;
127  wB[c0]++;
128  }
129  }
130  else if ((ibType[c0] == Mesh::IBTYPE_FLUID) &&
131  (ibType[c1] == Mesh::IBTYPE_FLUID))
132  {
133  // leave as is
134  }
135  else
136  {
137  // setup to get zero corrections
138  rCell[c0] = NumTypeTraits<X>::getZero();
139  rCell[c1] = NumTypeTraits<X>::getZero();
140  matrix.setDirichlet(c0);
141  matrix.setDirichlet(c1);
142  }
143  }
144 
145  // set the phi for boundary cells as average of the ib face values
146  for(int c=0; c<nCells; c++)
147  {
148  if (wB[c] > 0)
149  cellPhi[c] = xB[c] / T_Scalar(wB[c]);
150  }
151  }
152 
153 private:
156 };
157 
158 #endif
virtual void zero()
Definition: Array.h:281
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
const StorageSite & getIBFaces() const
Definition: Mesh.h:111
Vector< T_Scalar, 3 > VectorT3
CRMatrix< Diag, OffDiag, X > CCMatrix
Definition: Field.h:14
NumTypeTraits< X >::T_Scalar T_Scalar
Definition: Mesh.h:49
OffDiag & getCoeff10(const int np)
Definition: CRMatrix.h:131
Field ibType
Definition: GeomFields.h:38
const CRConnectivity & getAllFaceCells() const
Definition: Mesh.cpp:378
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
void discretize(const Mesh &mesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
const StorageSite & getFaces() const
Definition: Mesh.h:108
Field ibFaceIndex
Definition: GeomFields.h:40
const StorageSite & getCells() const
Definition: Mesh.h:109
OffDiag & getCoeff01(const int np)
Definition: CRMatrix.h:126
CCMatrix::OffDiagArray OffDiagArray
int getCount() const
Definition: StorageSite.h:39
void setDirichlet(const int nr)
Definition: CRMatrix.h:887
PairWiseAssembler & getPairWiseAssembler(const CRConnectivity &pairs)
Definition: CRMatrix.h:867
vector< Mesh * > MeshList
Definition: Mesh.h:439
CCMatrix::PairWiseAssembler CCAssembler
GenericIBDiscretization(const MeshList &meshes, const GeomFields &geomFields, Field &phiField)