Memosa-FVM  0.2
BatteryBinaryElectrolyteDiscretization.h
Go to the documentation of this file.
1 #ifndef _BATTERYBINARYELECTROLYTEDISCRETIZATION_H_
2 #define _BATTERYBINARYELECTROLYTEDISCRETIZATION_H_
3 
4 #include "CRMatrix.h"
5 #include "Field.h"
6 #include "MultiField.h"
7 #include "MultiFieldMatrix.h"
8 #include "Mesh.h"
9 #include "Discretization.h"
10 #include "StorageSite.h"
11 #include "DiagonalMatrix.h"
12 #include "Gradient.h"
13 #include "DiagonalTensor.h"
14 /*
15  template<class T>
16  inline T harmonicAverage(const T& x0, const T& x1)
17  {
18  const T sum = x0+x1;
19  if (x0+x1 != NumTypeTraits<T>::getZero())
20  return 2.0*x0*x1/sum;
21  else
22  return sum;
23  }
24 */
25 
26 template<class X, class Diag, class OffDiag>
28  {
29  public:
30 
32 
34  typedef typename CCMatrix::DiagArray DiagArray;
36 
37  typedef Gradient<X> XGrad;
39 
40  typedef Array<X> XArray;
44 
46 
48  const GeomFields& geomFields,
49  Field& varField,
50  const Field& diffusivityField,
51  const Field& concField,
52  const Field& concGradientField,
53  const Field& tempField,
54  const int ElectrolyteMeshID) :
55  Discretization(meshes),
56  _geomFields(geomFields),
57  _varField(varField),
58  _diffusivityField(diffusivityField),
59  _concField(concField),
60  _concGradientField(concGradientField),
61  _tempField(tempField),
62  _ElectrolyteMeshID(ElectrolyteMeshID)
63  {}
64 
65  void discretize(const Mesh& mesh, MultiFieldMatrix& mfmatrix,
66  MultiField& xField, MultiField& rField)
67  {
68  if (mesh.getID() == _ElectrolyteMeshID)
69  {
70  // electric potential variables
71  const StorageSite& cells = mesh.getCells();
72 
73  const MultiField::ArrayIndex cVarIndex(&_varField,&cells);
74 
75  //CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndex,cVarIndex));
76 
77  const VectorT3Array& cellCentroid =
78  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
79  const TArray& cellVolume =
80  dynamic_cast<const TArray&>(_geomFields.volume[cells]);
81 
82  //DiagArray& diag = matrix.getDiag();
83 
84  //const XArray& xCell = dynamic_cast<const XArray&>(xField[cVarIndex]); // may not need here
85  XArray& rCell = dynamic_cast<XArray&>(rField[cVarIndex]);
86 
87  // lnspeciesConcentration variables
88  const TArray& lnSpecConcCell = dynamic_cast<const TArray&>(_concField[cells]);
89 
90  const GradArray& lnSpecConcGradCell =
91  dynamic_cast<const GradArray&>(_concGradientField[cells]);
92 
93  const TArray& diffCell =
94  dynamic_cast<const TArray&>(_diffusivityField[cells]);
95 
96  const TArray& tempCell =
97  dynamic_cast<const TArray&>(_tempField[cells]);
98 
99  const IntArray& ibType = dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
100 
101 
102  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
103  {
104  const FaceGroup& fg = *fgPtr;
105 
106  const StorageSite& faces = fg.site;
107  const int nFaces = faces.getCount();
108  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
109  const VectorT3Array& faceArea =
110  dynamic_cast<const VectorT3Array&>(_geomFields.area[faces]);
111  const TArray& faceAreaMag =
112  dynamic_cast<const TArray&>(_geomFields.areaMag[faces]);
113  const VectorT3Array& faceCentroid =
114  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[faces]);
115  //CCAssembler& assembler = matrix.getPairWiseAssembler(faceCells);
116  for(int f=0; f<nFaces; f++)
117  {
118  const int c0 = faceCells(f,0);
119  const int c1 = faceCells(f,1);
120 
121  T_Scalar vol0 = cellVolume[c0];
122  T_Scalar vol1 = cellVolume[c1];
123 
124  VectorT3 ds=cellCentroid[c1]-cellCentroid[c0];
125 
126  // for ib faces ignore the solid cell and use the face centroid for diff metric
127  if (((ibType[c0] == Mesh::IBTYPE_FLUID)
128  && (ibType[c1] == Mesh::IBTYPE_BOUNDARY)) ||
129  ((ibType[c1] == Mesh::IBTYPE_FLUID)
130  && (ibType[c0] == Mesh::IBTYPE_BOUNDARY)))
131  {
132  if (ibType[c0] == Mesh::IBTYPE_FLUID)
133  {
134  vol1 = 0.;
135  ds = faceCentroid[f]-cellCentroid[c0];
136  }
137  else
138  {
139  vol0 = 0.;
140  ds = cellCentroid[c1]-faceCentroid[f];
141  }
142  }
143 
144  T_Scalar faceDiffusivity(1.0);
145  if (vol0 == 0.)
146  faceDiffusivity = diffCell[c1];
147  else if (vol1 == 0.)
148  faceDiffusivity = diffCell[c0];
149  else
150  faceDiffusivity = harmonicAverage(diffCell[c0],diffCell[c1]);
151 
152  T_Scalar faceTemp(300.0);
153  if (vol0 == 0.)
154  faceTemp = tempCell[c1];
155  else if (vol1 == 0.)
156  faceTemp = tempCell[c0];
157  else
158  faceTemp = harmonicAverage(tempCell[c0],tempCell[c1]);
159 
160 
161  //convert diffusivity for ln term in battery equation
162  const T_Scalar transportNumber = 0.4;
163  const T_Scalar R = 8.314;
164  const T_Scalar F = 96485.0;
165 
166  faceDiffusivity = faceDiffusivity*(-2.0)*R*faceTemp/F*(1.0-transportNumber);
167 
168  const T_Scalar diffMetric = faceAreaMag[f]*faceAreaMag[f]/dot(faceArea[f],ds);
169  const T_Scalar diffCoeff = faceDiffusivity*diffMetric;
170  const VectorT3 secondaryCoeff = faceDiffusivity*(faceArea[f]-ds*diffMetric);
171 
172  const XGrad gradF = (lnSpecConcGradCell[c0]*vol0+lnSpecConcGradCell[c1]*vol1)/(vol0+vol1);
173 
174  const X dFluxSecondary = gradF*secondaryCoeff;
175 
176  const X dFlux = diffCoeff*(lnSpecConcCell[c1]-lnSpecConcCell[c0]) + dFluxSecondary;
177 
178  rCell[c0] += dFlux;
179  rCell[c1] -= dFlux;
180 
181  //assembler.getCoeff01(f) +=diffCoeff;
182  //assembler.getCoeff10(f) +=diffCoeff;
183 
184  //diag[c0] -= diffCoeff;
185  //diag[c1] -= diffCoeff;
186 
187  //cout <<"dflux" << dFlux << endl;
188  /*
189  cout << " c0 and c1 " << c0 << " " << c1 << endl;
190  cout << " diffcell " << diffCell[c0] << " " << diffCell[c1] << " " << faceDiffusivity << endl;
191  cout << " diffmetric " << diffMetric << endl;
192  cout << "diffCoeff " << diffCoeff << endl;
193  */
194 
195 
196 
197  }
198  }
199  }
200  }
201  private:
209  };
210 
211 #endif
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
Field coordinate
Definition: GeomFields.h:19
T harmonicAverage(const T &x0, const T &x1)
Definition: Mesh.h:28
const FaceGroupList & getAllFaceGroups() const
Definition: Mesh.h:193
Definition: Field.h:14
Definition: Mesh.h:49
void discretize(const Mesh &mesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
Field ibType
Definition: GeomFields.h:38
BatteryBinaryElectrolyteDiscretization(const MeshList &meshes, const GeomFields &geomFields, Field &varField, const Field &diffusivityField, const Field &concField, const Field &concGradientField, const Field &tempField, const int ElectrolyteMeshID)
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
const StorageSite & getCells() const
Definition: Mesh.h:109
Field volume
Definition: GeomFields.h:26
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
int getCount() const
Definition: StorageSite.h:39
Field area
Definition: GeomFields.h:23
Field areaMag
Definition: GeomFields.h:25
T dot(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:253
int getID() const
Definition: Mesh.h:106
vector< Mesh * > MeshList
Definition: Mesh.h:439
StorageSite site
Definition: Mesh.h:40