Memosa-FVM  0.2
BatteryLinearizePotentialInterface< X, Diag, OffDiag > Class Template Reference

#include <BatteryLinearizePotentialInterface.h>

Collaboration diagram for BatteryLinearizePotentialInterface< X, Diag, OffDiag >:

Public Types

typedef NumTypeTraits< X >
::T_Scalar 
T_Scalar
 
typedef CRMatrix< Diag,
OffDiag, X > 
CCMatrix
 
typedef CCMatrix::DiagArray DiagArray
 
typedef Array< T_ScalarTArray
 
typedef Array< X > XArray
 
typedef Vector< T_Scalar, 3 > VectorT3
 
typedef Array< VectorT3VectorT3Array
 

Public Member Functions

 BatteryLinearizePotentialInterface (const GeomFields &geomFields, Field &varField, Field &speciesConcentrationField, Field &temperatureField, const T_Scalar RRConstant, const bool Anode, const bool Cathode)
 
void discretize (const Mesh &mesh, const Mesh &parentMesh, const Mesh &otherMesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
 

Private Attributes

const GeomFields_geomFields
 
Field_varField
 
Field_speciesConcentrationField
 
Field_temperatureField
 
const T_Scalar _RRConstant
 
const bool _Anode
 
const bool _Cathode
 

Detailed Description

template<class X, class Diag, class OffDiag>
class BatteryLinearizePotentialInterface< X, Diag, OffDiag >

Definition at line 24 of file BatteryLinearizePotentialInterface.h.

Member Typedef Documentation

template<class X, class Diag, class OffDiag>
typedef CRMatrix<Diag,OffDiag,X> BatteryLinearizePotentialInterface< X, Diag, OffDiag >::CCMatrix

Definition at line 28 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef CCMatrix::DiagArray BatteryLinearizePotentialInterface< X, Diag, OffDiag >::DiagArray

Definition at line 29 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef NumTypeTraits<X>::T_Scalar BatteryLinearizePotentialInterface< X, Diag, OffDiag >::T_Scalar

Definition at line 27 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef Array<T_Scalar> BatteryLinearizePotentialInterface< X, Diag, OffDiag >::TArray

Definition at line 30 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef Vector<T_Scalar,3> BatteryLinearizePotentialInterface< X, Diag, OffDiag >::VectorT3

Definition at line 32 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef Array<VectorT3> BatteryLinearizePotentialInterface< X, Diag, OffDiag >::VectorT3Array

Definition at line 33 of file BatteryLinearizePotentialInterface.h.

template<class X, class Diag, class OffDiag>
typedef Array<X> BatteryLinearizePotentialInterface< X, Diag, OffDiag >::XArray

Definition at line 31 of file BatteryLinearizePotentialInterface.h.

Constructor & Destructor Documentation

template<class X, class Diag, class OffDiag>
BatteryLinearizePotentialInterface< X, Diag, OffDiag >::BatteryLinearizePotentialInterface ( const GeomFields geomFields,
Field varField,
Field speciesConcentrationField,
Field temperatureField,
const T_Scalar  RRConstant,
const bool  Anode,
const bool  Cathode 
)
inline

Member Function Documentation

template<class X, class Diag, class OffDiag>
void BatteryLinearizePotentialInterface< X, Diag, OffDiag >::discretize ( const Mesh mesh,
const Mesh parentMesh,
const Mesh otherMesh,
MultiFieldMatrix mfmatrix,
MultiField xField,
MultiField rField 
)
inline

Definition at line 53 of file BatteryLinearizePotentialInterface.h.

References BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_Anode, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_Cathode, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_geomFields, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_RRConstant, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_speciesConcentrationField, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_temperatureField, BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_varField, GeomFields::areaMag, Mesh::getCellCells(), Mesh::getCells(), CRMatrix< T_Diag, T_OffDiag, X >::getCoeff(), StorageSite::getCount(), CRMatrix< T_Diag, T_OffDiag, X >::getDiag(), Mesh::getFaceCells(), MultiFieldMatrix::getMatrix(), Mesh::getOtherFaceGroupSite(), Mesh::getParentFaceGroupSite(), and StorageSite::getSelfCount().

Referenced by BatteryModel< T >::Impl::linearizePotential().

56  {
57  const StorageSite& cells = mesh.getCells();
58  const StorageSite& faces = mesh.getParentFaceGroupSite();
59 
60  // shell mesh info
61  const MultiField::ArrayIndex cVarIndex(&_varField,&cells);
62  CCMatrix& matrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndex,cVarIndex));
63  const XArray& xCell = dynamic_cast<const XArray&>(xField[cVarIndex]);
64  const CRConnectivity& cellCells = mesh.getCellCells();
65  XArray& rCell = dynamic_cast<XArray&>(rField[cVarIndex]);
66  DiagArray& diag = matrix.getDiag();
67 
68  //shell mesh species concentration values
69  const XArray& eSpecConcCell =
70  dynamic_cast<const XArray&>(_speciesConcentrationField[cells]);
71 
72  //shell mesh temperature values
73  const XArray& eTempCell =
74  dynamic_cast<const XArray&>(_temperatureField[cells]);
75 
76 
77  // In the following, parent is assumed to be the electrolyte, and
78  // the other mesh is assumed to be electrode when implimenting
79  // the Butler-Volmer equations
80 
81  // parent mesh info
82  const CRConnectivity& parentFaceCells = parentMesh.getFaceCells(faces);
83  const StorageSite& parentCells = parentMesh.getCells();
84  const MultiField::ArrayIndex cVarIndexParent(&_varField,&parentCells);
85  XArray& rParentCell = dynamic_cast<XArray&>(rField[cVarIndexParent]);
86  CCMatrix& parentmatrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndexParent,cVarIndexParent));
87  DiagArray& parentdiag = parentmatrix.getDiag();
88  const TArray& faceAreaMag =
89  dynamic_cast<const TArray&>(_geomFields.areaMag[faces]);
90 
91  // other mesh info
92  const StorageSite& otherFaces = mesh.getOtherFaceGroupSite();
93  const CRConnectivity& otherFaceCells = otherMesh.getFaceCells(otherFaces);
94  const StorageSite& otherCells = otherMesh.getCells();
95  const MultiField::ArrayIndex cVarIndexOther(&_varField,&otherCells);
96  XArray& rOtherCell = dynamic_cast<XArray&>(rField[cVarIndexOther]);
97  CCMatrix& othermatrix = dynamic_cast<CCMatrix&>(mfmatrix.getMatrix(cVarIndexOther,cVarIndexOther));
98  DiagArray& otherdiag = othermatrix.getDiag();
99 
100  // set constants for entire shell
101  const T_Scalar F = 96485.0; // C/mol
102  const T_Scalar k = _RRConstant;
103  T_Scalar csMax = 26000.0;// mol/m^3
104  if (_Anode){
105  csMax = 26390.0;}
106  if (_Cathode){
107  csMax = 22860.0;}
108 
109  const T_Scalar alpha_a = 0.5;
110  const T_Scalar alpha_c = 0.5;
111  const T_Scalar R = 8.314; // J/mol/K
112  const T_Scalar dU_dT = -0.0011; // V/K
113 
114  for (int f=0; f<faces.getCount(); f++)
115  {
116  //get parent mesh fluxes and coeffs
117  int c0p = parentFaceCells(f,0);
118  int c1p = parentFaceCells(f,1);
119  if (c1p < parentCells.getSelfCount())
120  {
121  // c0 is ghost cell and c1 is boundry cell, so swap cell numbers
122  // so that c1p refers to the ghost cell in the following
123  int temp = c0p;
124  c0p = c1p;
125  c1p = temp;
126  }
127 
128  const X parentFlux = rParentCell[c1p]; // inward shell flux on the left
129  const OffDiag dRC0dXC3 = parentmatrix.getCoeff(c1p, c0p);
130  const Diag dRC0dXC0 = parentdiag[c1p];
131 
132  //get other mesh fluxes and coeffs
133  int c0o = otherFaceCells(f,0);
134  int c1o = otherFaceCells(f,1);
135  if (c1o < otherCells.getSelfCount())
136  {
137  // c0 is ghost cell and c1 is boundry cell, so swap cell numbers
138  // so that c1o refers to the ghost cell in the following
139  int temp = c0o;
140  c0o = c1o;
141  c1o = temp;
142  }
143 
144  const X otherFlux = rOtherCell[c1o]; // inward shell flux on the right
145  const OffDiag dRC0dXC2 = othermatrix.getCoeff(c1o, c0o);
146  const OffDiag dRC0dXC1 = otherdiag[c1o];
147 
148 
149  //now put flux information from meshes into shell cells
150  const int c0 = f;
151  const int c1 = cellCells(f,0);
152  const int c2 = cellCells(f,1);
153  const int c3 = cellCells(f,2);
154 
155  const T_Scalar Temp = eTempCell[c0]; // K , c0 and c1 temps are equal at convergence
156  const T_Scalar C_a = alpha_a*F/R/Temp;
157  const T_Scalar C_c = alpha_c*F/R/Temp;
158  const T_Scalar Area = faceAreaMag[c0];
159  T_Scalar Ce_star = eSpecConcCell[c0];
160  T_Scalar Cs_star = eSpecConcCell[c1];
161 
162 
163 
164  //avoid nans during iterations
165  if (Ce_star < 0)
166  {
167  cout << "ERROR: Ce_star < 0, Ce_star=" << Ce_star << endl; Ce_star = 0.0;
168  }
169  if (Cs_star < 0)
170  {
171  cout << "ERROR: Cs_star < 0, Cs_star=" << Cs_star << endl; Cs_star = 0.0;
172  }
173  if (Cs_star > csMax){ Cs_star = 0.9*csMax; cout << "ERROR: Cs > CsMax" << endl;}
174 
175  const T_Scalar SOC = Cs_star/csMax;
176 
177  T_Scalar U_ref = 0.1; // V
178  if (_Anode){
179  U_ref = -0.16 + 1.32*exp(-3.0*SOC)+10.0*exp(-2000.0*SOC);}
180  if (_Cathode){
181  U_ref = 4.19829 + 0.0565661*tanh(-14.5546*SOC + 8.60942) - 0.0275479*(1.0/pow((0.998432-SOC),0.492465) - 1.90111) - 0.157123*exp(-0.04738*pow(SOC,8.0)) + 0.810239*exp(-40.0*(SOC-0.133875));}
182 
183  const T_Scalar i0_star = k*F*Area*pow(Ce_star,alpha_c)*pow((csMax-Cs_star),alpha_a)*pow(Cs_star,alpha_c);
184 
185  const T_Scalar Phis_star = xCell[c1];
186  const T_Scalar Phie_star = xCell[c0];
187  const T_Scalar U = U_ref - (Temp - 298.0)*dU_dT;
188  T_Scalar eta_star = Phis_star-Phie_star-U;
189 
190  //cout << eta_star << endl;
191 
192  const T_Scalar i_star = i0_star*(exp(C_a*eta_star)-exp(-1*C_c*eta_star));
193  const T_Scalar dIdPhiS_star = i0_star*(C_a*exp(C_a*eta_star)+C_c*exp(-1*C_c*eta_star));
194  const T_Scalar dIdPhiE_star = -1*i0_star*(C_a*exp(C_a*eta_star)+C_c*exp(-1*C_c*eta_star));
195 
196  // left(parent) shell cell - 3 neighbors
197  // flux balance
198  OffDiag& offdiagC0_C1 = matrix.getCoeff(c0, c1);
199  OffDiag& offdiagC0_C2 = matrix.getCoeff(c0, c2);
200  OffDiag& offdiagC0_C3 = matrix.getCoeff(c0, c3);
201 
202  rCell[c0] = otherFlux + parentFlux;
203  offdiagC0_C1 = dRC0dXC1;
204  offdiagC0_C3 = dRC0dXC3;
205  offdiagC0_C2 = dRC0dXC2;
206  diag[c0] = dRC0dXC0;
207 
208  // right(other) shell cell - 2 neighbors
209  // BV(jump) condition
210  OffDiag& offdiagC1_C0 = matrix.getCoeff(c1, c0);
211  OffDiag& offdiagC1_C2 = matrix.getCoeff(c1, c2);
212 
213  rCell[c1] = otherFlux - (i_star + dIdPhiS_star*(xCell[c1]-Phis_star) + dIdPhiE_star*(xCell[c0]-Phie_star));
214  offdiagC1_C0 = -1*dIdPhiE_star;
215  offdiagC1_C2 = dRC0dXC2;
216  diag[c1] = dRC0dXC1 - dIdPhiS_star;
217 
218  //make sure diag is < 0
219  if (diag[c1] > 0.0)
220  {
221  cout << "Warning: Diag > 0" << endl;
222  }
223 
224  // set other coeffs to zero for right shell cell
225  OffDiag& offdiagC1_C3 = matrix.getCoeff(c1, c3);
226  offdiagC1_C3 = 0.0;
227 
228  // some output of prevailing values once per shell - useful for testing
229 
230  /*if (c0 == 0){
231  cout << "i0_star: " << i0_star << endl;
232  cout << "Phi_s: " << Phis_star << " Phi_e: " << Phie_star << " i: " << i_star << " Flux: " << otherFlux << " dIdPhis: " << dIdPhiS_star << " dIdPhie: " << dIdPhiE_star << endl;
233  cout <<"Diag: " << diag[c1] << " dRdXc2: " << offdiagC1_C2 << " dRdXc0: " << offdiagC1_C0 << endl;
234  cout << " " << endl;
235  }*/
236 
237  //cout << "ParentFlux: " << parentFlux << " otherFlux: " << otherFlux << endl;
238  }
239 
240  }
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
int getSelfCount() const
Definition: StorageSite.h:40
const StorageSite & getParentFaceGroupSite() const
Definition: Mesh.h:329
const StorageSite & getOtherFaceGroupSite() const
Definition: Mesh.h:332
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
const StorageSite & getCells() const
Definition: Mesh.h:109
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
int getCount() const
Definition: StorageSite.h:39
Field areaMag
Definition: GeomFields.h:25

Member Data Documentation

template<class X, class Diag, class OffDiag>
const bool BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_Anode
private
template<class X, class Diag, class OffDiag>
const bool BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_Cathode
private
template<class X, class Diag, class OffDiag>
const GeomFields& BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_geomFields
private
template<class X, class Diag, class OffDiag>
const T_Scalar BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_RRConstant
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_speciesConcentrationField
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_temperatureField
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizePotentialInterface< X, Diag, OffDiag >::_varField
private

The documentation for this class was generated from the following file: