Memosa-FVM  0.2
ElecDiffusionDiscretization.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 _ELECDIFFUSIONDISCRETIZATION_H_
6 #define _ELECDIFFUSIONDISCRETIZATION_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 "Gradient.h"
17 #include "DiagonalTensor.h"
18 /*
19 template<class T>
20 inline T harmonicAverage(const T& x0, const T& x1)
21 {
22  const T sum = x0+x1;
23  if (x0+x1 != NumTypeTraits<T>::getZero())
24  return 2.0*x0*x1/sum;
25  else
26  return sum;
27 }
28 */
29 
30 template<class X, class Diag, class OffDiag>
32 {
33 public:
34 
36 
38  typedef typename CCMatrix::DiagArray DiagArray;
40 
41  typedef Gradient<X> XGrad;
42 
44  typedef Array<X> XArray;
48 
50 
52  const GeomFields& geomFields,
53  Field& varField,
54  const Field& diffusivityField,
55  const Field& varGradientField) :
56  Discretization(meshes),
57  _geomFields(geomFields),
58  _varField(varField),
59  _diffusivityField(diffusivityField),
60  _varGradientField(varGradientField)
61  {}
62 
63  void discretize(const Mesh& mesh, MultiFieldMatrix& mfmatrix,
64  MultiField& xField, MultiField& rField)
65  {
66  const StorageSite& cells = mesh.getCells();
67  const StorageSite& faces = mesh.getFaces();
68  const MultiField::ArrayIndex cVarIndex(&_varField,&cells);
69  CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndex,
70  cVarIndex));
71 
72  const VectorT3Array& faceArea =
73  dynamic_cast<const VectorT3Array&>(_geomFields.area[faces]);
74 
75  const TArray& faceAreaMag =
76  dynamic_cast<const TArray&>(_geomFields.areaMag[faces]);
77 
78  const VectorT3Array& cellCentroid =
79  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
80 
81  const VectorT3Array& faceCentroid =
82  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[faces]);
83 
84  const TArray& cellVolume =
85  dynamic_cast<const TArray&>(_geomFields.volume[cells]);
86 
87  const CRConnectivity& faceCells = mesh.getAllFaceCells();
88 
89  CCAssembler& assembler = matrix.getPairWiseAssembler(faceCells);
90  DiagArray& diag = matrix.getDiag();
91 
92  const XArray& xCell = dynamic_cast<const XArray&>(xField[cVarIndex]);
93  XArray& rCell = dynamic_cast<XArray&>(rField[cVarIndex]);
94 
95  const GradArray& xGradCell =
96  dynamic_cast<const GradArray&>(_varGradientField[cells]);
97 
98  const TArray& diffCell =
99  dynamic_cast<const TArray&>(_diffusivityField[cells]);
100 
101  const IntArray& ibType = dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
102 
103  const int nFaces = faces.getCount();
104  for(int f=0; f<nFaces; f++)
105  {
106  const int c0 = faceCells(f,0);
107  const int c1 = faceCells(f,1);
108 
109  T_Scalar vol0 = cellVolume[c0];
110  T_Scalar vol1 = cellVolume[c1];
111 
112  VectorT3 ds=cellCentroid[c1]-cellCentroid[c0];
113 
114  // for ib faces ignore the solid cell and use the face centroid for diff metric
115  if (((ibType[c0] == Mesh::IBTYPE_FLUID)
116  && (ibType[c1] == Mesh::IBTYPE_BOUNDARY)) ||
117  ((ibType[c1] == Mesh::IBTYPE_FLUID)
118  && (ibType[c0] == Mesh::IBTYPE_BOUNDARY)))
119  {
120  if (ibType[c0] == Mesh::IBTYPE_FLUID)
121  {
122  vol1 = 0.;
123  ds = faceCentroid[f]-cellCentroid[c0];
124  }
125  else
126  {
127  vol0 = 0.;
128  ds = cellCentroid[c1]-faceCentroid[f];
129  }
130  }
131 
132  T_Scalar faceDiffusivity(1.0);
133  if (vol0 == 0.)
134  faceDiffusivity = diffCell[c1];
135  else if (vol1 == 0.)
136  faceDiffusivity = diffCell[c0];
137  else
138  faceDiffusivity = harmonicAverage(diffCell[c0],diffCell[c1]);
139 
140  const T_Scalar diffMetric = faceAreaMag[f]*faceAreaMag[f]/dot(faceArea[f],ds);
141  const T_Scalar diffCoeff = faceDiffusivity*diffMetric;
142  const VectorT3 secondaryCoeff = faceDiffusivity*(faceArea[f]-ds*diffMetric);
143 
144  const XGrad gradF = (xGradCell[c0]*vol0+xGradCell[c1]*vol1)/(vol0+vol1);
145 
146  const X dFluxSecondary = gradF*secondaryCoeff;
147 
148  const X dFlux = diffCoeff*(xCell[c1]-xCell[c0]) + dFluxSecondary;
149 
150  rCell[c0][1] += dFlux[1];
151  rCell[c1][1] -= dFlux[1];
152 
153  assembler.getCoeff01(f)[3] +=diffCoeff;
154  assembler.getCoeff10(f)[3] +=diffCoeff;
155 
156  diag[c0][3] -= diffCoeff;
157  diag[c1][3] -= diffCoeff;
158  }
159  }
160 private:
165 };
166 
167 #endif
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
Field coordinate
Definition: GeomFields.h:19
T harmonicAverage(const T &x0, const T &x1)
Definition: Field.h:14
NumTypeTraits< X >::T_Scalar T_Scalar
Definition: Mesh.h:49
OffDiag & getCoeff10(const int np)
Definition: CRMatrix.h:131
Array< Diag > & getDiag()
Definition: CRMatrix.h:856
CCMatrix::PairWiseAssembler CCAssembler
Field ibType
Definition: GeomFields.h:38
const CRConnectivity & getAllFaceCells() const
Definition: Mesh.cpp:378
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
ElecDiffusionDiscretization(const MeshList &meshes, const GeomFields &geomFields, Field &varField, const Field &diffusivityField, const Field &varGradientField)
const StorageSite & getFaces() const
Definition: Mesh.h:108
const StorageSite & getCells() const
Definition: Mesh.h:109
void discretize(const Mesh &mesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
Field volume
Definition: GeomFields.h:26
OffDiag & getCoeff01(const int np)
Definition: CRMatrix.h:126
CRMatrix< Diag, OffDiag, X > CCMatrix
int getCount() const
Definition: StorageSite.h:39
Field area
Definition: GeomFields.h:23
PairWiseAssembler & getPairWiseAssembler(const CRConnectivity &pairs)
Definition: CRMatrix.h:867
Field areaMag
Definition: GeomFields.h:25
T dot(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:253
vector< Mesh * > MeshList
Definition: Mesh.h:439