Memosa-FVM  0.2
SpeciesModel_impl.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 #include "Mesh.h"
6 #include <sstream>
7 
8 #include "NumType.h"
9 #include "Array.h"
10 #include "Field.h"
11 #include "CRConnectivity.h"
12 #include "LinearSystem.h"
13 //#include "FieldSet.h"
14 #include "StorageSite.h"
15 #include "MultiFieldMatrix.h"
16 #include "CRMatrix.h"
17 #include "FluxJacobianMatrix.h"
18 #include "DiagonalMatrix.h"
19 #include "GenericBCS.h"
20 #include "Vector.h"
24 #include "AMG.h"
25 #include "Linearizer.h"
26 #include "GradientModel.h"
28 #include "SourceDiscretization.h"
29 #include "LinearizeInterfaceJump.h"
31 
32 template<class T>
33 class SpeciesModel<T>::Impl
34 {
35 public:
36  typedef Array<T> TArray;
42 
43  Impl(const GeomFields& geomFields,
44  const MeshList& meshes,
45  const int nSpecies) :
46  _meshes(meshes),
47  _geomFields(geomFields),
48  _niters(0),
49  _nSpecies(nSpecies),
50  _speciesModelFields("speciesModel")
51  {
52 
53  const int numMeshes = _meshes.size();
54 
55  for (int m=0; m<_nSpecies; m++)
56  {
57  SpeciesVCMap *svcmap = new SpeciesVCMap();
58  _vcMapVector.push_back(svcmap);
59  SpeciesBCMap *sbcmap = new SpeciesBCMap();
60  _bcMapVector.push_back(sbcmap);
61  SpeciesFields *sFields = new SpeciesFields("species");
62  _speciesFieldsVector.push_back(sFields);
63  MFRPtr *iNorm = new MFRPtr();
64  _initialNormVector.push_back(iNorm);
65  MFRPtr *rCurrent = new MFRPtr();
66  _currentResidual.push_back(rCurrent);
67 
68  for (int n=0; n<numMeshes; n++)
69  {
70 
71  const Mesh& mesh = *_meshes[n];
72  SpeciesVC<T> *vc(new SpeciesVC<T>());
73  vc->vcType = "flow";
74  (*svcmap)[mesh.getID()] = vc;
75 
76  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
77  {
78  const FaceGroup& fg = *fgPtr;
79  SpeciesBC<T> *bc(new SpeciesBC<T>());
80 
81  (*sbcmap)[fg.id] = bc;
82 
83  if ((fg.groupType == "wall") ||
84  (fg.groupType == "symmetry"))
85  {
86  bc->bcType = "SpecifiedMassFlux";
87  }
88  else if ((fg.groupType == "velocity-inlet") ||
89  (fg.groupType == "pressure-outlet"))
90  {
91  bc->bcType = "SpecifiedMassFraction";
92  }
93  else
94  throw CException("SpeciesModel: unknown face group type "
95  + fg.groupType);
96  }
97  }
98  }
99  }
100 
101  void init()
102  {
103  const int numMeshes = _meshes.size();
104 
105  for (int m=0; m<_nSpecies; m++)
106  {
107  const SpeciesVCMap& svcmap = *_vcMapVector[m];
108  const SpeciesBCMap& sbcmap = *_bcMapVector[m];
109  SpeciesFields& sFields = *_speciesFieldsVector[m];
110  //MFRPtr& iNorm = *_initialNormVector[m];
111 
112  for (int n=0; n<numMeshes; n++)
113  {
114  const Mesh& mesh = *_meshes[n];
115 
116  const StorageSite& cells = mesh.getCells();
117  const StorageSite& allFaces = mesh.getFaces();
118 
119  typename SpeciesVCMap::const_iterator pos = svcmap.find(mesh.getID());
120  if (pos==svcmap.end())
121  {
122  throw CException("SpeciesModel: Error in VC Map");
123  }
124 
125  const SpeciesVC<T>& vc = *(pos->second);
126 
127 
128  //mass fraction
129 
130  shared_ptr<TArray> mFCell(new TArray(cells.getCount()));
131 
132  if (!mesh.isDoubleShell())
133  {
134  *mFCell = vc["initialMassFraction"];
135  }
136  else
137  {
138  // double shell mesh cells take on values of parents
139  typename SpeciesVCMap::const_iterator posParent = svcmap.find(mesh.getParentMeshID());
140  typename SpeciesVCMap::const_iterator posOther = svcmap.find(mesh.getOtherMeshID());
141  const SpeciesVC<T>& vcP = *(posParent->second);
142  const SpeciesVC<T>& vcO = *(posOther->second);
143 
144  const int NumberOfCells = cells.getCount();
145  for (int c=0; c<NumberOfCells; c++)
146  {
147  if ((c < NumberOfCells/4)||(c >= 3*NumberOfCells/4))
148  {
149  (*mFCell)[c] = vcP["initialMassFraction"];
150  }
151  else
152  {
153  (*mFCell)[c] = vcO["initialMassFraction"];
154  }
155  }
156  }
157  /*
158  //Initialize to exp for ln term testing in electric model
159  const VectorT3Array& cellCentroid =
160  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
161 
162  for (int c=0; c<cells.getCount(); c++)
163  {
164  VectorT3 CellCent = cellCentroid[c];
165  (*mFCell)[c] = exp(pow(CellCent[0],2));
166  }*/
167 
168 
169  /*if (n==0)
170  {
171  *mFCell =_options["initialMassFraction0"];
172  }
173  else if (n==1)
174  {
175  *mFCell = _options["initialMassFraction1"];
176  }
177  else if (n==2)
178  {
179  *mFCell = _options["initialMassFraction2"];
180  }
181  else if (n==3)
182  {
183  *mFCell = _options["initialMassFraction3"];
184  }
185  else if (n==4)
186  {
187  *mFCell = _options["initialMassFraction4"];
188  }
189  else
190  {
191  *mFCell =_options["initialMassFraction0"];
192  }
193 
194  if (mesh.isDoubleShell())
195  {
196  char parentInitial[21];
197  char otherInitial[21];
198  sprintf(parentInitial, "initialMassFraction%d", mesh.getParentMeshID());
199  sprintf(otherInitial, "initialMassFraction%d", mesh.getOtherMeshID());
200 
201  for (int c=0; c<cells.getSelfCount(); c++)
202  {
203  if (c < cells.getSelfCount()/2)
204  {
205  (*mFCell)[c] = _options[parentInitial];
206  }
207  else
208  {
209  (*mFCell)[c] = _options[otherInitial];
210  }
211  }
212  }*/
213 
214 
215  //*mFCell = _options["initialMassFraction"];
216 
217  /* //Initialize to 1-D linear solution in x direction
218  const VectorT3Array& cellCentroid =
219  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
220 
221  for (int c=0; c<cells.getCount(); c++)
222  {
223  VectorT3 CellCent = cellCentroid[c];
224  (*mFCell)[c] = -0.05*CellCent[0] + 0.5;
225  } */
226 
227  /*//Initialize to specialized concentrations (for now)
228  const VectorT3Array& cellCentroid =
229  dynamic_cast<const VectorT3Array&>(_geomFields.coordinate[cells]);
230 
231  for (int c=0; c<cells.getCount(); c++)
232  {
233  VectorT3 CellCent = cellCentroid[c];
234  if (n==0)
235  {
236  (*mFCell)[c] = 1000.0;
237  }
238  elseif (n==1)
239  {
240  (*mFCell)[c] = 0.0;
241 
242  (*mFCell)[c] = -0.05*CellCent[0] + 0.5;
243  }*/
244 
245  sFields.massFraction.addArray(cells,mFCell);
246 
247  if (_options.ButlerVolmer)
248  {
249  sFields.massFractionElectricModel.addArray(cells,dynamic_pointer_cast<ArrayBase>(mFCell->newCopy()));
250  }
251 
252  if (_options.transient)
253  {
254  sFields.massFractionN1.addArray(cells,
255  dynamic_pointer_cast<ArrayBase>(mFCell->newCopy()));
256  if (_options.timeDiscretizationOrder > 1)
257  sFields.massFractionN2.addArray(cells,
258  dynamic_pointer_cast<ArrayBase>(mFCell->newCopy()));
259 
260  }
261 
262  //diffusivity
263  shared_ptr<TArray> diffusivityCell(new TArray(cells.getCount()));
264  *diffusivityCell = vc["massDiffusivity"];
265  sFields.diffusivity.addArray(cells,diffusivityCell);
266 
267  //source
268  shared_ptr<TArray> sCell(new TArray(cells.getCount()));
269  *sCell = T(0.);
270  sFields.source.addArray(cells,sCell);
271 
272  //create a zero field
273  shared_ptr<TArray> zeroCell(new TArray(cells.getCount()));
274  *zeroCell = T(0.0);
275  sFields.zero.addArray(cells,zeroCell);
276 
277  //create a one field
278  shared_ptr<TArray> oneCell(new TArray(cells.getCount()));
279  *oneCell = T(1.0);
280  sFields.one.addArray(cells,oneCell);
281 
282  //initial temparature gradient array
283  shared_ptr<TGradArray> gradT(new TGradArray(cells.getCount()));
284  gradT->zero();
285  _speciesModelFields.speciesGradient.addArray(cells,gradT);
286 
287  //inital convection flux at faces
288  shared_ptr<TArray> convFlux(new TArray(allFaces.getCount()));
289  convFlux->zero();
290  sFields.convectionFlux.addArray(allFaces,convFlux);
291 
292  //mass flux at faces
293  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
294  {
295  const FaceGroup& fg = *fgPtr;
296  const StorageSite& faces = fg.site;
297 
298  shared_ptr<TArray> fluxFace(new TArray(faces.getCount()));
299 
300  fluxFace->zero();
301  sFields.massFlux.addArray(faces,fluxFace);
302 
303  }
304  foreach(const FaceGroupPtr fgPtr, mesh.getInterfaceGroups())
305  {
306  const FaceGroup& fg = *fgPtr;
307  const StorageSite& faces = fg.site;
308 
309  shared_ptr<TArray> fluxFace(new TArray(faces.getCount()));
310 
311  fluxFace->zero();
312  sFields.massFlux.addArray(faces,fluxFace);
313 
314  }
315 
316  //electric potential (for coupling to ElectricModel)
317  // only needed once for each mesh (not depenedent on species)
318  if (m==0)
319  {
320  shared_ptr<TArray> ePotCell(new TArray(cells.getCount()));
321  ePotCell->zero();
322  sFields.elecPotential.addArray(cells,ePotCell);
323  }
324  }
325 
326  sFields.diffusivity.syncLocal();
327  //iNorm = MFRPtr();
328  }
329  _niters =0;
330  }
331 
332  SpeciesFields& getSpeciesFields(const int speciesId) {return *_speciesFieldsVector[speciesId];}
333 
334  SpeciesVCMap& getVCMap(const int speciesId) {return *_vcMapVector[speciesId];}
335  SpeciesBCMap& getBCMap(const int speciesId) {return *_bcMapVector[speciesId];}
336 
337  SpeciesBC<T>& getBC(const int id, const int speciesId ) {return *(*_bcMapVector[speciesId])[id];}
338 
339  SpeciesModelOptions<T>& getOptions() {return _options;}
340 
341  void updateTime()
342  {
343  const int numMeshes = _meshes.size();
344 
345  for (int m=0; m<_nSpecies; m++)
346  {
347  SpeciesFields& sFields = *_speciesFieldsVector[m];
348 
349  for (int n=0; n<numMeshes; n++)
350  {
351  const Mesh& mesh = *_meshes[n];
352 
353  const StorageSite& cells = mesh.getCells();
354  TArray& mF =
355  dynamic_cast<TArray&>(sFields.massFraction[cells]);
356  TArray& mFN1 =
357  dynamic_cast<TArray&>(sFields.massFractionN1[cells]);
358 
359  if (_options.timeDiscretizationOrder > 1)
360  {
361  TArray& mFN2 =
362  dynamic_cast<TArray&>(sFields.massFractionN2[cells]);
363  mFN2 = mFN1;
364  }
365  mFN1 = mF;
366  }
367  }
368  }
369 
370  void initLinearization(LinearSystem& ls, const int& m)
371  {
372  SpeciesFields& sFields = *_speciesFieldsVector[m];
373  const int numMeshes = _meshes.size();
374 
375  for (int n=0; n<numMeshes; n++)
376  {
377  const Mesh& mesh = *_meshes[n];
378 
379  const StorageSite& cells = mesh.getCells();
380  MultiField::ArrayIndex tIndex(&sFields.massFraction,&cells);
381 
382  ls.getX().addArray(tIndex,sFields.massFraction.getArrayPtr(cells));
383 
384  const CRConnectivity& cellCells = mesh.getCellCells();
385 
386  shared_ptr<Matrix> m(new CRMatrix<T,T,T>(cellCells));
387 
388  ls.getMatrix().addMatrix(tIndex,tIndex,m);
389 
390  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
391  {
392  const FaceGroup& fg = *fgPtr;
393  const StorageSite& faces = fg.site;
394 
395  MultiField::ArrayIndex fIndex(&sFields.massFlux,&faces);
396  ls.getX().addArray(fIndex,sFields.massFlux.getArrayPtr(faces));
397 
398  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
399 
400  shared_ptr<Matrix> mft(new FluxJacobianMatrix<T,T>(faceCells));
401  ls.getMatrix().addMatrix(fIndex,tIndex,mft);
402 
403  shared_ptr<Matrix> mff(new DiagonalMatrix<T,T>(faces.getCount()));
404  ls.getMatrix().addMatrix(fIndex,fIndex,mff);
405  }
406 
407  foreach(const FaceGroupPtr fgPtr, mesh.getInterfaceGroups())
408  {
409  const FaceGroup& fg = *fgPtr;
410  const StorageSite& faces = fg.site;
411 
412  MultiField::ArrayIndex fIndex(&sFields.massFlux,&faces);
413  ls.getX().addArray(fIndex,sFields.massFlux.getArrayPtr(faces));
414 
415  const CRConnectivity& faceCells = mesh.getFaceCells(faces);
416 
417  shared_ptr<Matrix> mft(new FluxJacobianMatrix<T,T>(faceCells));
418  ls.getMatrix().addMatrix(fIndex,tIndex,mft);
419 
420  shared_ptr<Matrix> mff(new DiagonalMatrix<T,T>(faces.getCount()));
421  ls.getMatrix().addMatrix(fIndex,fIndex,mff);
422  }
423 
424  }
425  }
426 
427  void linearize(LinearSystem& ls, const int& m)
428  {
429  const SpeciesVCMap& svcmap = *_vcMapVector[m];
430  const SpeciesBCMap& sbcmap = *_bcMapVector[m];
431  SpeciesFields& sFields = *_speciesFieldsVector[m];
432 
433  GradientModel<T> speciesGradientModel(_meshes,sFields.massFraction,
434  _speciesModelFields.speciesGradient,_geomFields);
435  speciesGradientModel.compute();
436 
437  DiscrList discretizations;
438 
439  shared_ptr<Discretization>
441  (_meshes,_geomFields,
442  sFields.massFraction,
443  sFields.diffusivity,
444  _speciesModelFields.speciesGradient));
445  discretizations.push_back(dd);
446 
447  shared_ptr<Discretization>
449  (_meshes,_geomFields,
450  sFields.massFraction,
451  sFields.convectionFlux,
452  sFields.zero,
453  _speciesModelFields.speciesGradient,
454  _options.useCentralDifference));
455  discretizations.push_back(cd);
456 
457 
458  shared_ptr<Discretization>
460  (_meshes,
461  _geomFields,
462  sFields.massFraction,
463  sFields.source));
464  discretizations.push_back(sd);
465 
466  if (_options.transient)
467  {
468  shared_ptr<Discretization>
470  (_meshes,_geomFields,
471  sFields.massFraction,
472  sFields.massFractionN1,
473  sFields.massFractionN2,
474  sFields.one,
475  _options["timeStep"]));
476 
477  discretizations.push_back(td);
478  }
479 
480  shared_ptr<Discretization>
482  (_meshes,_geomFields,sFields.massFraction));
483 
484  discretizations.push_back(ibm);
485 
486  Linearizer linearizer;
487 
488  linearizer.linearize(discretizations,_meshes,ls.getMatrix(),
489  ls.getX(), ls.getB());
490 
491  const int numMeshes = _meshes.size();
492 
493  /* linearize shell mesh */
494 
495  for (int n=0; n<numMeshes; n++)
496  {
497  const Mesh& mesh = *_meshes[n];
498  if (mesh.isDoubleShell())
499  {
500  const int parentMeshID = mesh.getParentMeshID();
501  const int otherMeshID = mesh.getOtherMeshID();
502  const Mesh& parentMesh = *_meshes[parentMeshID];
503  const Mesh& otherMesh = *_meshes[otherMeshID];
504 
505  if (_options.ButlerVolmer)
506  {
507  bool Cathode = false;
508  bool Anode = false;
509  if (n == _options["ButlerVolmerCathodeShellMeshID"])
510  {
511  Cathode = true;
512  }
513  else if (n == _options["ButlerVolmerAnodeShellMeshID"])
514  {
515  Anode = true;
516  }
517 
518  LinearizeSpeciesInterface<T, T, T> lbv (_geomFields,
519  _options["ButlerVolmerRRConstant"],
520  _options["A_coeff"],
521  _options["B_coeff"],
522  _options["interfaceUnderRelax"],
523  Anode,
524  Cathode,
525  sFields.massFraction,
527  sFields.elecPotential);
528 
529  lbv.discretize(mesh, parentMesh, otherMesh, ls.getMatrix(), ls.getX(), ls.getB() );
530 
531  }
532  else
533  {
534  LinearizeInterfaceJump<T, T, T> lsm (_options["A_coeff"],
535  _options["B_coeff"],
536  sFields.massFraction);
537 
538  lsm.discretize(mesh, parentMesh, otherMesh, ls.getMatrix(), ls.getX(), ls.getB() );
539  }
540  }
541  }
542 
543  /* boundary and interface condition */
544 
545  for (int n=0; n<numMeshes; n++)
546  {
547  const Mesh& mesh = *_meshes[n];
548 
549  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
550  {
551  const FaceGroup& fg = *fgPtr;
552  const StorageSite& faces = fg.site;
553 
554  typename SpeciesBCMap::const_iterator pos = sbcmap.find(fg.id);
555  if (pos==sbcmap.end())
556  {
557  throw CException("SpeciesModel: Error in BC Map");
558  }
559 
560  const SpeciesBC<T>& bc = *(pos->second);
561 
562  GenericBCS<T,T,T> gbc(faces,mesh,
563  _geomFields,
564  sFields.massFraction,
565  sFields.massFlux,
566  ls.getMatrix(), ls.getX(), ls.getB());
567 
568  if (bc.bcType == "SpecifiedMassFraction")
569  {
571  bT(bc.getVal("specifiedMassFraction"),faces);
572  if (sFields.convectionFlux.hasArray(faces))
573  {
574  const TArray& convectingFlux =
575  dynamic_cast<const TArray&>
576  (sFields.convectionFlux[faces]);
577  const int nFaces = faces.getCount();
578 
579  for(int f=0; f<nFaces; f++)
580  {
581  if (convectingFlux[f] > 0.)
582  {
583  gbc.applyExtrapolationBC(f);
584  }
585  else
586  {
587  gbc.applyDirichletBC(f,bT[f]);
588  }
589  }
590  }
591  else
592  gbc.applyDirichletBC(bT);
593  }
594  else if (bc.bcType == "SpecifiedMassFlux")
595  {
596  const T specifiedFlux(bc["specifiedMassFlux"]);
597  gbc.applyNeumannBC(specifiedFlux);
598  }
599  else if ((bc.bcType == "Symmetry"))
600  {
601  T zeroFlux(NumTypeTraits<T>::getZero());
602  gbc.applyNeumannBC(zeroFlux);
603  }
604  else
605  throw CException(bc.bcType + " not implemented for SpeciesModel");
606  }
607 
608  foreach(const FaceGroupPtr fgPtr, mesh.getInterfaceGroups())
609  {
610  const FaceGroup& fg = *fgPtr;
611  const StorageSite& faces = fg.site;
612  GenericBCS<T,T,T> gbc(faces,mesh,
613  _geomFields,
614  sFields.massFraction,
615  sFields.massFlux,
616  ls.getMatrix(), ls.getX(), ls.getB());
617 
618  gbc.applyInterfaceBC();
619  }
620  }
621  }
622 
623  T getMassFluxIntegral(const Mesh& mesh, const int faceGroupId, const int m)
624  {
625  SpeciesFields& sFields = *_speciesFieldsVector[m];
626 
627  T r(0.);
628  bool found = false;
629  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups())
630  {
631  const FaceGroup& fg = *fgPtr;
632  if (fg.id == faceGroupId)
633  {
634  const StorageSite& faces = fg.site;
635  const int nFaces = faces.getCount();
636  const TArray& massFlux =
637  dynamic_cast<const TArray&>(sFields.massFlux[faces]);
638  for(int f=0; f<nFaces; f++)
639  r += massFlux[f];
640  found=true;
641  }
642  }
643 
644  foreach(const FaceGroupPtr fgPtr, mesh.getInterfaceGroups())
645  {
646  const FaceGroup& fg = *fgPtr;
647  if (fg.id == faceGroupId)
648  {
649  const StorageSite& faces = fg.site;
650  const int nFaces = faces.getCount();
651  const TArray& massFlux =
652  dynamic_cast<const TArray&>(sFields.massFlux[faces]);
653  for(int f=0; f<nFaces; f++)
654  r += massFlux[f];
655  found=true;
656  }
657  }
658 
659 
660  if (!found)
661  throw CException("getMassFluxIntegral: invalid faceGroupID");
662  return r;
663  }
664 
665 T getAverageMassFraction(const Mesh& mesh, const int m)
666  {
667  SpeciesFields& sFields = *_speciesFieldsVector[m];
668  const StorageSite& cells = mesh.getCells();
669  const TArray& mFCell = dynamic_cast<const TArray&>(sFields.massFraction[cells]);
670  const TArray& cellVolume = dynamic_cast<const TArray&>(_geomFields.volume[cells]);
671  T totalVolume = 0.0;
672  T weightedMassFraction = 0.0;
673  for(int c=0; c<cells.getSelfCount(); c++)
674  {
675  totalVolume += cellVolume[c];
676  weightedMassFraction += mFCell[c]*cellVolume[c];
677  }
678  return weightedMassFraction/totalVolume;
679  }
680 
681 
682  void advance(const int niter)
683  {
684  for(int n=0; n<niter; n++)
685  {
686  bool allConverged=true;
687  for (int m=0; m<_nSpecies; m++)
688  {
689  MFRPtr& iNorm = *_initialNormVector[m];
690  MFRPtr& rCurrent = *_currentResidual[m];
691 
692  LinearSystem ls;
693  initLinearization(ls, m);
694 
695  ls.initAssembly();
696 
697  linearize(ls, m);
698 
699  ls.initSolve();
700 
701  MFRPtr rNorm(_options.getLinearSolver().solve(ls));
702 
703  if (!iNorm) iNorm = rNorm;
704 
705  MFRPtr normRatio((*rNorm)/(*iNorm));
706 
707  cout << "Species Number: " << m << endl;
708  cout << _niters << ": " << *rNorm << endl;
709 
710  _options.getLinearSolver().cleanup();
711 
712  ls.postSolve();
713  ls.updateSolution();
714 
715  _niters++;
716 
717  rCurrent = rNorm;
718 
719  if (!(*rNorm < _options.absoluteTolerance ||
720  *normRatio < _options.relativeTolerance))
721  allConverged=false;
722  }
723  if (allConverged)
724  break;
725  }
726  }
727 
728  void printBCs()
729  {
730  for (int m=0; m<_nSpecies; m++)
731  {
732  const SpeciesBCMap& sbcmap = *_bcMapVector[m];
733  cout << "Species Number :" << m << endl;
734 
735  for(typename SpeciesBCMap::const_iterator pos=sbcmap.begin();
736  pos!=sbcmap.end();
737  ++pos)
738  {
739  cout << "Face Group " << pos->first << ":" << endl;
740  cout << " bc type " << pos->second->bcType << endl;
741  foreach(typename SpeciesBC<T>::value_type& vp, *(pos->second))
742  {
743  cout << " " << vp.first << " " << vp.second.constant << endl;
744  }
745  }
746  }
747  }
748 
749  T getMassFractionResidual(const int speciesId)
750  {
751  MFRPtr& rCurrent = *_currentResidual[speciesId];
752  SpeciesFields& sFields = *_speciesFieldsVector[speciesId];
753  const Field& massFractionField = sFields.massFraction;
754  ArrayBase& residualArray = (*rCurrent)[massFractionField];
755  T *arrayData = (T*)(residualArray.getData());
756  const T residual = arrayData[0];
757  return residual;
758  }
759 
760 
761 private:
764 
765  vector<SpeciesFields*> _speciesFieldsVector;
766 
767  vector<SpeciesBCMap*> _bcMapVector;
768  vector<SpeciesVCMap*> _vcMapVector;
769 
771 
772  //MFRPtr _initialNorm;
773  vector<MFRPtr*> _initialNormVector;
774  int _niters;
775  const int _nSpecies;
776 
778 
779  //MFRPtr _currentResidual;
780  vector<MFRPtr*> _currentResidual;
781 };
782 
783 template<class T>
785  const MeshList& meshes,
786  const int nSpecies) :
787  Model(meshes),
788  _impl(new Impl(geomFields,meshes,nSpecies))
789 {
790  logCtor();
791 }
792 
793 
794 template<class T>
796 {
797  logDtor();
798 }
799 
800 template<class T>
801 void
803 {
804  _impl->init();
805 }
806 
807 template<class T>
809 SpeciesModel<T>::getSpeciesFields(const int speciesId) {return _impl->getSpeciesFields(speciesId);}
810 
811 template<class T>
813 SpeciesModel<T>::getBCMap(const int speciesId) {return _impl->getBCMap(speciesId);}
814 
815 template<class T>
817 SpeciesModel<T>::getVCMap(const int speciesId) {return _impl->getVCMap(speciesId);}
818 
819 template<class T>
821 SpeciesModel<T>::getBC(const int id, const int speciesId) {return _impl->getBC(id, speciesId);}
822 
823 template<class T>
825 SpeciesModel<T>::getOptions() {return _impl->getOptions();}
826 
827 
828 template<class T>
829 void
831 {
832  _impl->printBCs();
833 }
834 
835 template<class T>
836 void
837 SpeciesModel<T>::advance(const int niter)
838 {
839  _impl->advance(niter);
840 }
841 
842 template<class T>
843 void
845 {
846  _impl->updateTime();
847 }
848 
849 template<class T>
850 T
851 SpeciesModel<T>::getMassFluxIntegral(const Mesh& mesh, const int faceGroupId, const int m)
852 {
853  return _impl->getMassFluxIntegral(mesh, faceGroupId, m);
854 }
855 
856 template<class T>
857 T
859 {
860  return _impl->getAverageMassFraction(mesh, m);
861 }
862 
863 template<class T>
864 T
866 {
867  return _impl->getMassFractionResidual(speciesId);
868 }
const FaceGroupList & getBoundaryFaceGroups() const
Definition: Mesh.h:187
bool isDoubleShell() const
Definition: Mesh.h:324
void initAssembly()
Impl(const GeomFields &geomFields, const MeshList &meshes, const int nSpecies)
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
int getSelfCount() const
Definition: StorageSite.h:40
T getAverageMassFraction(const Mesh &mesh, const int m)
std::map< int, SpeciesVC< T > * > SpeciesVCMap
Definition: SpeciesModel.h:24
bool hasArray(const StorageSite &s) const
Definition: Field.cpp:37
Definition: Mesh.h:28
void advance(const int niter)
Field massFractionElectricModel
Definition: SpeciesFields.h:29
T getMassFluxIntegral(const Mesh &mesh, const int faceGroupId, const int m)
Gradient< T > TGradType
T getMassFractionResidual(const int speciesId)
Definition: Field.h:14
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)
Definition: Mesh.h:49
SpeciesVCMap & getVCMap(const int speciesId)
string bcType
Definition: SpeciesBC.h:17
Field massFractionN2
Definition: SpeciesFields.h:23
#define logCtor()
Definition: RLogInterface.h:26
string groupType
Definition: Mesh.h:42
FloatVal< T > getVal(const string varName) const
Definition: FloatVarDict.h:85
Field elecPotential
Definition: SpeciesFields.h:28
int getOtherMeshID() const
Definition: Mesh.h:327
SpeciesModel(const GeomFields &geomFields, const MeshList &meshes, const int nSpecies)
const GeomFields & _geomFields
const int id
Definition: Mesh.h:41
void updateSolution()
void discretize(const Mesh &mesh, const Mesh &parentMesh, const Mesh &otherMesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
vector< SpeciesVCMap * > _vcMapVector
virtual void init()
T getMassFractionResidual(const int speciesId)
void initSolve()
virtual ~SpeciesModel()
T getAverageMassFraction(const Mesh &mesh, const int m)
SpeciesModelOptions< T > & getOptions()
vector< shared_ptr< Discretization > > DiscrList
const MeshList _meshes
const StorageSite & getFaces() const
Definition: Mesh.h:108
SpeciesVCMap & getVCMap(const int speciesId)
const MeshList _meshes
Definition: Model.h:29
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
Definition: Model.h:13
const StorageSite & getCells() const
Definition: Mesh.h:109
T getMassFluxIntegral(const Mesh &mesh, const int faceGroupId, const int m)
void applyInterfaceBC(const int f) const
Definition: GenericBCS.h:325
#define logDtor()
Definition: RLogInterface.h:33
void addArray(const StorageSite &, shared_ptr< ArrayBase > a)
Definition: Field.cpp:72
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
Definition: Array.h:14
int getParentMeshID() const
Definition: Mesh.h:326
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)
string vcType
Definition: SpeciesBC.h:28
void linearize(LinearSystem &ls, const int &m)
vector< SpeciesFields * > _speciesFieldsVector
Field massFractionN1
Definition: SpeciesFields.h:22
virtual void * getData() const =0
int getCount() const
Definition: StorageSite.h:39
CRMatrix< T, T, T > T_Matrix
MultiField & getB()
Definition: LinearSystem.h:33
vector< MFRPtr * > _currentResidual
SpeciesModelOptions< T > & getOptions()
shared_ptr< MultiFieldReduction > MFRPtr
void addArray(const ArrayIndex &aIndex, shared_ptr< ArrayBase > a)
Definition: MultiField.cpp:270
const FaceGroupList & getInterfaceGroups() const
Definition: Mesh.h:190
MultiField & getX()
Definition: LinearSystem.h:32
Field convectionFlux
Definition: SpeciesFields.h:20
vector< SpeciesBCMap * > _bcMapVector
Vector< T, 3 > VectorT3
void initLinearization(LinearSystem &ls, const int &m)
shared_ptr< ArrayBase > getArrayPtr(const StorageSite &)
Definition: Field.cpp:63
Field massFraction
Definition: SpeciesFields.h:16
SpeciesModelOptions< T > _options
void syncLocal()
Definition: Field.cpp:334
int getID() const
Definition: Mesh.h:106
virtual void linearize(DiscrList &discretizations, const MeshList &meshes, MultiFieldMatrix &matrix, MultiField &x, MultiField &b)
Definition: Linearizer.cpp:17
void discretize(const Mesh &mesh, const Mesh &parentMesh, const Mesh &otherMesh, MultiFieldMatrix &mfmatrix, MultiField &xField, MultiField &rField)
SpeciesBCMap & getBCMap(const int speciesId)
MultiFieldMatrix & getMatrix()
Definition: LinearSystem.h:37
vector< Mesh * > MeshList
Definition: Mesh.h:439
std::map< int, SpeciesBC< T > * > SpeciesBCMap
Definition: SpeciesModel.h:23
StorageSite site
Definition: Mesh.h:40
SpeciesBCMap & getBCMap(const int speciesId)
vector< MFRPtr * > _initialNormVector