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

#include <BatteryLinearizeThermalInterface.h>

Collaboration diagram for BatteryLinearizeThermalInterface< 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

 BatteryLinearizeThermalInterface (const GeomFields &geomFields, Field &varField, Field &speciesConcentrationField, Field &potentialField, 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_potentialField
 
const T_Scalar _RRConstant
 
const bool _Anode
 
const bool _Cathode
 

Detailed Description

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

Definition at line 24 of file BatteryLinearizeThermalInterface.h.

Member Typedef Documentation

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

Definition at line 28 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 29 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 27 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 30 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 32 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 33 of file BatteryLinearizeThermalInterface.h.

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

Definition at line 31 of file BatteryLinearizeThermalInterface.h.

Constructor & Destructor Documentation

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

Member Function Documentation

template<class X, class Diag, class OffDiag>
void BatteryLinearizeThermalInterface< 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 BatteryLinearizeThermalInterface.h.

References BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_Anode, BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_Cathode, BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_geomFields, BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_potentialField, BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_RRConstant, BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_speciesConcentrationField, BatteryLinearizeThermalInterface< 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::linearizeThermal().

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 potential values
73  const XArray& ePotentialCell =
74  dynamic_cast<const XArray&>(_potentialField[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 
113  const T_Scalar Peltier = 0.0;
114  const T_Scalar dU_dT = -0.0011; // V/K
115 
116  for (int f=0; f<faces.getCount(); f++)
117  {
118  //get parent mesh fluxes and coeffs
119  int c0p = parentFaceCells(f,0);
120  int c1p = parentFaceCells(f,1);
121  if (c1p < parentCells.getSelfCount())
122  {
123  // c0 is ghost cell and c1 is boundry cell, so swap cell numbers
124  // so that c1p refers to the ghost cell in the following
125  int temp = c0p;
126  c0p = c1p;
127  c1p = temp;
128  }
129 
130  const X parentFlux = rParentCell[c1p]; // inward shell flux on the left
131  const OffDiag dRC0dXC3 = parentmatrix.getCoeff(c1p, c0p);
132  const Diag dRC0dXC0 = parentdiag[c1p];
133 
134  //get other mesh fluxes and coeffs
135  int c0o = otherFaceCells(f,0);
136  int c1o = otherFaceCells(f,1);
137  if (c1o < otherCells.getSelfCount())
138  {
139  // c0 is ghost cell and c1 is boundry cell, so swap cell numbers
140  // so that c1o refers to the ghost cell in the following
141  int temp = c0o;
142  c0o = c1o;
143  c1o = temp;
144  }
145 
146  const X otherFlux = rOtherCell[c1o]; // inward shell flux on the right
147  const OffDiag dRC0dXC2 = othermatrix.getCoeff(c1o, c0o);
148  const OffDiag dRC0dXC1 = otherdiag[c1o];
149 
150 
151  //now put flux information from meshes into shell cells
152  const int c0 = f;
153  const int c1 = cellCells(f,0);
154  const int c2 = cellCells(f,1);
155  const int c3 = cellCells(f,2);
156 
157  T_Scalar Ce_star = eSpecConcCell[c0];
158  T_Scalar Cs_star = eSpecConcCell[c1];
159 
160  //avoid nans during iterations
161  if (Ce_star < 0)
162  {
163  cout << "ERROR: Ce_star < 0, Ce_star=" << Ce_star << endl; Ce_star = 0.0;
164  }
165  if (Cs_star < 0)
166  {
167  cout << "ERROR: Cs_star < 0, Cs_star=" << Cs_star << endl; Cs_star = 0.0;
168  }
169  if (Cs_star > csMax){ Cs_star = 0.9*csMax; cout << "ERROR: Cs > CsMax" << endl;}
170 
171  const T_Scalar SOC = Cs_star/csMax;
172 
173  T_Scalar U_ref = 0.1; // V
174  if (_Anode){
175  U_ref = -0.16 + 1.32*exp(-3.0*SOC)+10.0*exp(-2000.0*SOC);}
176  if (_Cathode){
177  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));}
178 
179  const T_Scalar Area = faceAreaMag[c0];
180  const T_Scalar Phis_star = ePotentialCell[c1];
181  const T_Scalar Phie_star = ePotentialCell[c0];
182 
183  const T_Scalar Temp = xCell[c0]; // K , c0 and c1 temps are equal at convergence
184  const T_Scalar U = U_ref - (Temp - 298.0)*dU_dT;
185  const T_Scalar eta_star = Phis_star-Phie_star-U;
186  const T_Scalar C_a = alpha_a*F/R/Temp;
187  const T_Scalar C_c = alpha_c*F/R/Temp;
188 
189  const T_Scalar i0_star = k*F*Area*pow(Ce_star,alpha_c)*pow((csMax-Cs_star),alpha_a)*pow(Cs_star,alpha_c);
190  const T_Scalar i_star = i0_star*(exp(C_a*eta_star)-exp(-1*C_c*eta_star));
191 
192 
193  // decide which temperature to use. c0 and c1 will have same temps at convergence,
194  // but use the one that will add to diagonal dominance based on dI_dT
195  const T_Scalar dR0_dT_HeatSourceSign = -1.0*(eta_star)*(eta_star+Peltier);
196  T_Scalar dI_dTe = 0.0;
197  T_Scalar dI_dTs = 0.0;
198  if (dR0_dT_HeatSourceSign < 0.0)
199  {
200  dI_dTe = -1.0*i0_star*F*eta_star/R/Temp/Temp*(alpha_a*exp(C_a*eta_star)+alpha_c*exp(-1.0*C_c*eta_star));
201  }
202  else
203  {
204  dI_dTs = -1.0*i0_star*F*eta_star/R/Temp/Temp*(alpha_a*exp(C_a*eta_star)+alpha_c*exp(-1.0*C_c*eta_star));
205  }
206 
207  // left(parent) shell cell - 3 neighbors
208  // flux balance
209  OffDiag& offdiagC0_C1 = matrix.getCoeff(c0, c1);
210  OffDiag& offdiagC0_C2 = matrix.getCoeff(c0, c2);
211  OffDiag& offdiagC0_C3 = matrix.getCoeff(c0, c3);
212 
213  rCell[c0] = otherFlux + parentFlux + (eta_star + Peltier)*i_star;
214 
215  // Flux jacobians
216  offdiagC0_C3 = dRC0dXC3;
217  offdiagC0_C2 = dRC0dXC2;
218  diag[c0] = dRC0dXC0;
219  offdiagC0_C1 = dRC0dXC1;
220 
221  // heat source jacobian additions
222  diag[c0] += (eta_star + Peltier)*dI_dTe;
223  offdiagC0_C1 += (eta_star + Peltier)*dI_dTs;
224 
225  // right(other) shell cell - 1 neighbor
226  // temperature continuity
227  OffDiag& offdiagC1_C0 = matrix.getCoeff(c1, c0);
228 
229  rCell[c1] = xCell[c0] - xCell[c1];
230  offdiagC1_C0 = 1.0;
231  diag[c1] = -1.0;
232 
233  // set other coeffs to zero for right shell cell
234  OffDiag& offdiagC1_C2 = matrix.getCoeff(c1, c2);
235  offdiagC1_C2 = 0.0;
236  OffDiag& offdiagC1_C3 = matrix.getCoeff(c1, c3);
237  offdiagC1_C3 = 0.0;
238 
239  // some output of prevailing values once per shell - useful for testing
240 
241  /*if (c0 == 0){
242  cout << "i0_star: " << i0_star << endl;
243  cout << "Phi_s: " << Phis_star << " Phi_e: " << Phie_star << " i: " << i_star << " Flux: " << otherFlux << " dIdPhis: " << dIdPhiS_star << " dIdPhie: " << dIdPhiE_star << endl;
244  cout <<"Diag: " << diag[c1] << " dRdXc2: " << offdiagC1_C2 << " dRdXc0: " << offdiagC1_C0 << endl;
245  cout << " " << endl;
246  }*/
247 
248  //cout << "ParentFlux: " << parentFlux << " otherFlux: " << otherFlux << endl;
249  }
250 
251  }
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 BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_Anode
private
template<class X, class Diag, class OffDiag>
const bool BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_Cathode
private
template<class X, class Diag, class OffDiag>
const GeomFields& BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_geomFields
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_potentialField
private
template<class X, class Diag, class OffDiag>
const T_Scalar BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_RRConstant
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_speciesConcentrationField
private
template<class X, class Diag, class OffDiag>
Field& BatteryLinearizeThermalInterface< X, Diag, OffDiag >::_varField
private

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