47 _geomFields(geomFields),
50 _speciesModelFields(
"speciesModel")
53 const int numMeshes =
_meshes.size();
55 for (
int m=0; m<_nSpecies; m++)
58 _vcMapVector.push_back(svcmap);
60 _bcMapVector.push_back(sbcmap);
62 _speciesFieldsVector.push_back(sFields);
64 _initialNormVector.push_back(iNorm);
66 _currentResidual.push_back(rCurrent);
68 for (
int n=0; n<numMeshes; n++)
74 (*svcmap)[mesh.
getID()] = vc;
81 (*sbcmap)[fg.
id] = bc;
86 bc->
bcType =
"SpecifiedMassFlux";
88 else if ((fg.
groupType ==
"velocity-inlet") ||
91 bc->
bcType =
"SpecifiedMassFraction";
94 throw CException(
"SpeciesModel: unknown face group type "
103 const int numMeshes =
_meshes.size();
105 for (
int m=0; m<_nSpecies; m++)
112 for (
int n=0; n<numMeshes; n++)
119 typename SpeciesVCMap::const_iterator pos = svcmap.find(mesh.
getID());
120 if (pos==svcmap.end())
122 throw CException(
"SpeciesModel: Error in VC Map");
134 *mFCell = vc[
"initialMassFraction"];
139 typename SpeciesVCMap::const_iterator posParent = svcmap.find(mesh.
getParentMeshID());
140 typename SpeciesVCMap::const_iterator posOther = svcmap.find(mesh.
getOtherMeshID());
144 const int NumberOfCells = cells.
getCount();
145 for (
int c=0; c<NumberOfCells; c++)
147 if ((c < NumberOfCells/4)||(c >= 3*NumberOfCells/4))
149 (*mFCell)[c] = vcP[
"initialMassFraction"];
153 (*mFCell)[c] = vcO[
"initialMassFraction"];
247 if (_options.ButlerVolmer)
252 if (_options.transient)
255 dynamic_pointer_cast<ArrayBase>(mFCell->newCopy()));
256 if (_options.timeDiscretizationOrder > 1)
258 dynamic_pointer_cast<ArrayBase>(mFCell->newCopy()));
264 *diffusivityCell = vc[
"massDiffusivity"];
285 _speciesModelFields.speciesGradient.addArray(cells,gradT);
337 SpeciesBC<T>&
getBC(
const int id,
const int speciesId ) {
return *(*_bcMapVector[speciesId])[
id];}
343 const int numMeshes =
_meshes.size();
345 for (
int m=0; m<_nSpecies; m++)
349 for (
int n=0; n<numMeshes; n++)
359 if (_options.timeDiscretizationOrder > 1)
373 const int numMeshes =
_meshes.size();
375 for (
int n=0; n<numMeshes; n++)
434 _speciesModelFields.speciesGradient,_geomFields);
435 speciesGradientModel.
compute();
439 shared_ptr<Discretization>
444 _speciesModelFields.speciesGradient));
445 discretizations.push_back(dd);
447 shared_ptr<Discretization>
453 _speciesModelFields.speciesGradient,
454 _options.useCentralDifference));
455 discretizations.push_back(cd);
458 shared_ptr<Discretization>
464 discretizations.push_back(sd);
466 if (_options.transient)
468 shared_ptr<Discretization>
475 _options[
"timeStep"]));
477 discretizations.push_back(td);
480 shared_ptr<Discretization>
484 discretizations.push_back(ibm);
491 const int numMeshes =
_meshes.size();
495 for (
int n=0; n<numMeshes; n++)
505 if (_options.ButlerVolmer)
507 bool Cathode =
false;
509 if (n == _options[
"ButlerVolmerCathodeShellMeshID"])
513 else if (n == _options[
"ButlerVolmerAnodeShellMeshID"])
519 _options[
"ButlerVolmerRRConstant"],
522 _options[
"interfaceUnderRelax"],
545 for (
int n=0; n<numMeshes; n++)
554 typename SpeciesBCMap::const_iterator pos = sbcmap.find(fg.
id);
555 if (pos==sbcmap.end())
557 throw CException(
"SpeciesModel: Error in BC Map");
568 if (bc.
bcType ==
"SpecifiedMassFraction")
571 bT(bc.
getVal(
"specifiedMassFraction"),faces);
574 const TArray& convectingFlux =
575 dynamic_cast<const TArray&
>
577 const int nFaces = faces.
getCount();
579 for(
int f=0; f<nFaces; f++)
581 if (convectingFlux[f] > 0.)
583 gbc.applyExtrapolationBC(f);
587 gbc.applyDirichletBC(f,bT[f]);
592 gbc.applyDirichletBC(bT);
594 else if (bc.
bcType ==
"SpecifiedMassFlux")
596 const T specifiedFlux(bc[
"specifiedMassFlux"]);
597 gbc.applyNeumannBC(specifiedFlux);
599 else if ((bc.
bcType ==
"Symmetry"))
602 gbc.applyNeumannBC(zeroFlux);
632 if (fg.
id == faceGroupId)
635 const int nFaces = faces.
getCount();
638 for(
int f=0; f<nFaces; f++)
647 if (fg.
id == faceGroupId)
650 const int nFaces = faces.
getCount();
653 for(
int f=0; f<nFaces; f++)
661 throw CException(
"getMassFluxIntegral: invalid faceGroupID");
670 const TArray& cellVolume =
dynamic_cast<const TArray&
>(_geomFields.volume[cells]);
672 T weightedMassFraction = 0.0;
675 totalVolume += cellVolume[c];
676 weightedMassFraction += mFCell[c]*cellVolume[c];
678 return weightedMassFraction/totalVolume;
684 for(
int n=0; n<niter; n++)
686 bool allConverged=
true;
687 for (
int m=0; m<_nSpecies; m++)
689 MFRPtr& iNorm = *_initialNormVector[m];
690 MFRPtr& rCurrent = *_currentResidual[m];
693 initLinearization(ls, m);
701 MFRPtr rNorm(_options.getLinearSolver().solve(ls));
703 if (!iNorm) iNorm = rNorm;
705 MFRPtr normRatio((*rNorm)/(*iNorm));
707 cout <<
"Species Number: " << m << endl;
708 cout << _niters <<
": " << *rNorm << endl;
710 _options.getLinearSolver().cleanup();
719 if (!(*rNorm < _options.absoluteTolerance ||
720 *normRatio < _options.relativeTolerance))
730 for (
int m=0; m<_nSpecies; m++)
733 cout <<
"Species Number :" << m << endl;
735 for(
typename SpeciesBCMap::const_iterator pos=sbcmap.begin();
739 cout <<
"Face Group " << pos->first <<
":" << endl;
740 cout <<
" bc type " << pos->second->bcType << endl;
743 cout <<
" " << vp.first <<
" " << vp.second.constant << endl;
751 MFRPtr& rCurrent = *_currentResidual[speciesId];
754 ArrayBase& residualArray = (*rCurrent)[massFractionField];
755 T *arrayData = (T*)(residualArray.
getData());
756 const T residual = arrayData[0];
786 const int nSpecies) :
788 _impl(new
Impl(geomFields,meshes,nSpecies))
839 _impl->advance(niter);
853 return _impl->getMassFluxIntegral(mesh, faceGroupId, m);
860 return _impl->getAverageMassFraction(mesh, m);
867 return _impl->getMassFractionResidual(speciesId);
const FaceGroupList & getBoundaryFaceGroups() const
bool isDoubleShell() const
Impl(const GeomFields &geomFields, const MeshList &meshes, const int nSpecies)
shared_ptr< FaceGroup > FaceGroupPtr
T getAverageMassFraction(const Mesh &mesh, const int m)
std::map< int, SpeciesVC< T > * > SpeciesVCMap
bool hasArray(const StorageSite &s) const
void advance(const int niter)
Field massFractionElectricModel
T getMassFluxIntegral(const Mesh &mesh, const int faceGroupId, const int m)
T getMassFractionResidual(const int speciesId)
SpeciesBC< T > & getBC(const int id, const int speciesId)
Array< VectorT3 > VectorT3Array
SpeciesFields & getSpeciesFields(const int speciesId)
SpeciesBC< T > & getBC(const int id, const int speciesId)
SpeciesVCMap & getVCMap(const int speciesId)
FloatVal< T > getVal(const string varName) const
int getOtherMeshID() const
SpeciesModel(const GeomFields &geomFields, const MeshList &meshes, const int nSpecies)
const GeomFields & _geomFields
void discretize(const Mesh &mesh, const Mesh &parentMesh, const Mesh &otherMesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
pair< const Field *, const StorageSite * > ArrayIndex
vector< SpeciesVCMap * > _vcMapVector
T getMassFractionResidual(const int speciesId)
T getAverageMassFraction(const Mesh &mesh, const int m)
SpeciesModelOptions< T > & getOptions()
vector< shared_ptr< Discretization > > DiscrList
const StorageSite & getFaces() const
SpeciesVCMap & getVCMap(const int speciesId)
const CRConnectivity & getCellCells() const
const StorageSite & getCells() const
T getMassFluxIntegral(const Mesh &mesh, const int faceGroupId, const int m)
void applyInterfaceBC(const int f) const
void addArray(const StorageSite &, shared_ptr< ArrayBase > a)
const CRConnectivity & getFaceCells(const StorageSite &site) const
int getParentMeshID() const
void addMatrix(const Index &rowI, const Index &colI, shared_ptr< Matrix > m)
SpeciesFields & getSpeciesFields(const int speciesId)
Array< Gradient< T > > TGradArray
SpeciesModelFields _speciesModelFields
void advance(const int niter)
void linearize(LinearSystem &ls, const int &m)
vector< SpeciesFields * > _speciesFieldsVector
virtual void * getData() const =0
CRMatrix< T, T, T > T_Matrix
vector< MFRPtr * > _currentResidual
SpeciesModelOptions< T > & getOptions()
shared_ptr< MultiFieldReduction > MFRPtr
void addArray(const ArrayIndex &aIndex, shared_ptr< ArrayBase > a)
const FaceGroupList & getInterfaceGroups() const
vector< SpeciesBCMap * > _bcMapVector
void initLinearization(LinearSystem &ls, const int &m)
shared_ptr< ArrayBase > getArrayPtr(const StorageSite &)
SpeciesModelOptions< T > _options
virtual void linearize(DiscrList &discretizations, const MeshList &meshes, MultiFieldMatrix &matrix, MultiField &x, MultiField &b)
void discretize(const Mesh &mesh, const Mesh &parentMesh, const Mesh &otherMesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
SpeciesBCMap & getBCMap(const int speciesId)
MultiFieldMatrix & getMatrix()
vector< Mesh * > MeshList
std::map< int, SpeciesBC< T > * > SpeciesBCMap
SpeciesBCMap & getBCMap(const int speciesId)
vector< MFRPtr * > _initialNormVector