Memosa-FVM  0.2
BatteryPC_BCS.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 #ifndef _BATTERYPC_BCS_H_
6 #define _BATTERYPC_BCS_H_
7 
8 #include "Mesh.h"
9 
10 #include "NumType.h"
11 #include "Array.h"
12 #include "Vector.h"
13 #include "Field.h"
14 #include "CRConnectivity.h"
15 #include "StorageSite.h"
16 #include "MultiFieldMatrix.h"
17 #include "CRMatrix.h"
18 #include "FluxJacobianMatrix.h"
19 #include "DiagonalMatrix.h"
20 
21 template<class X, class Diag, class OffDiag>
23 {
24 public:
25 
27 
30 
32 
35 
38 
41 
42  typedef Array<X> XArray;
44 
45 
46  BatteryPC_BCS(const StorageSite& faces,
47  const Mesh& mesh,
48  const GeomFields& geomFields,
49  Field& varField,
50  Field& fluxField,
51  MultiFieldMatrix& matrix,
52  MultiField& xField, MultiField& rField) :
53  _faces(faces),
54  _cells(mesh.getCells()),
55  _ibType(dynamic_cast<const IntArray&>(geomFields.ibType[_cells])),
56  _faceCells(mesh.getFaceCells(_faces)),
57  _varField(varField),
58  _fluxField(fluxField),
61  _dRdX(dynamic_cast<CCMatrix&>(matrix.getMatrix(_xIndex,_xIndex))),
62  _dFluxdX(dynamic_cast<FMatrix&>(matrix.getMatrix(_fluxIndex,_xIndex))),
63  _dFluxdFlux(dynamic_cast<BBMatrix&>(matrix.getMatrix(_fluxIndex,_fluxIndex))),
64  _assembler(_dRdX.getPairWiseAssembler(_faceCells)),
65  _dRdXDiag(_dRdX.getDiag()),
66  _x(dynamic_cast<XArray&>(xField[_xIndex])),
67  _r(dynamic_cast<XArray&>(rField[_xIndex])),
68  _flux(dynamic_cast<XArray&>(xField[_fluxIndex])),
69  _rFlux(dynamic_cast<XArray&>(rField[_fluxIndex])),
70  _areaMagField(geomFields.areaMag),
71  _faceAreaMag(dynamic_cast<const TArray&>(_areaMagField[_faces])),
72  _areaField(geomFields.area),
73  _faceArea(dynamic_cast<const VectorT3Array&>(_areaField[_faces])),
74  _is2D(mesh.getDimension()==2)
75  {}
76 
77  void applySingleEquationDirichletBC(int f, const T_Scalar& bValue, const int v) const
78  {
79  const int c0 = _faceCells(f,0);
80  const int c1 = _faceCells(f,1);
81 
82  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
83  return;
84 
85  // the current value of flux and its Jacobians
86  const T_Scalar fluxB = -(_r[c1])[v];
87  //const T_Scalar dFluxdXC0 = -(_assembler.getCoeff10(f))(v,v);
88  const OffDiag dFluxdXC0_orig = -_assembler.getCoeff10(f);
89  const T_Scalar dFluxdXC1 = -(_dRdXDiag[c1])[v];
90  OffDiag dRC0dXC1_orig = _assembler.getCoeff01(f);
91  const T_Scalar dRC0dXC1 = dRC0dXC1_orig[v];
92 
93  // since we know the boundary value, compute the boundary
94  // x correction and it's contribution to the residual for c0; we
95  // can then eliminate the coefficient to the boundary cell
96 
97  const T_Scalar dXC1 = bValue - (_x[c1])[v];
98  const T_Scalar dFlux = dFluxdXC1*dXC1;
99  const T_Scalar dRC0 = dRC0dXC1*dXC1;
100  (_r[c0])[v] += dRC0;
101 
103 
104  // set the boundary value and make its correction equation an
105  // identity
106  (_x[c1])[v] = bValue;
110 
111  //setup the equation for the boundary flux correction
112  _dFluxdX.setCoeffL(f,dFluxdXC0_orig);
113  dRC0dXC1_orig[v] = NumTypeTraits<T_Scalar>::getZero();
114  _dFluxdX.setCoeffR(f,dRC0dXC1_orig);
115  (_flux[f])[v] = fluxB;
116  (_rFlux[f])[v] = dFlux;
117  Diag _dFluxdFlux_orig = _dFluxdFlux[f];
118  _dFluxdFlux_orig[v] = NumTypeTraits<T_Scalar>::getNegativeUnity();
119  _dFluxdFlux[f] = _dFluxdFlux_orig;
120  }
121 
122  void applySingleEquationDirichletBC(const FloatValEvaluator<T_Scalar>& bValue, const int v) const
123  {
124  for(int i=0; i<_faces.getCount(); i++)
125  applySingleEquationDirichletBC(i,bValue[i],v);
126  }
127 
129  const T_Scalar& specifiedFlux, const int v) const
130  {
131  const int c0 = _faceCells(f,0);
132  const int c1 = _faceCells(f,1);
133 
134  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
135  return;
136  // the current value of flux and its Jacobians
137  const T_Scalar fluxB = -(_r[c1])[v];
138 
139 
140  // since we know the boundary flux, compute the boundary flux
141  // correction and add it to the c0 residual; also eliminate
142  // coeff to the boundary cell and remove it from the ap coeff
143 
144  const T_Scalar dFlux = specifiedFlux*_faceAreaMag[f] - fluxB;
145  // setup the equation for the boundary value; the coefficients
146  // are already computed so just need to set the rhs
147  (_r[c1])[v] = dFlux;
148 
149  // mark this row as a "boundary" row so that we will update it
150  // after the overall system is solved
151  _dRdX.setBoundary(c1);
152 
153  // fix the boundary flux to the specified value
154  (_flux[f])[v] = specifiedFlux*_faceAreaMag[f];
155 
156  Diag _dFluxdFlux_orig = _dFluxdFlux[f];
157  _dFluxdFlux_orig[v] = NumTypeTraits<T_Scalar>::getNegativeUnity();
158  _dFluxdFlux[f] = _dFluxdFlux_orig;
159  }
160 
161  void applySingleEquationNeumannBC(const T_Scalar& bFlux, const int v) const
162  {
163  for(int i=0; i<_faces.getCount(); i++)
164  applySingleEquationNeumannBC(i,bFlux,v);
165  }
166 
167 protected:
172  const Field& _varField;
189  const bool _is2D;
190 
191 };
192 
193 #endif
194 
const StorageSite & _cells
const MultiField::ArrayIndex _fluxIndex
NumTypeTraits< X >::T_Scalar T_Scalar
Definition: BatteryPC_BCS.h:26
Array< OffDiag > OffDiagArray
Definition: BatteryPC_BCS.h:40
FMatrix & _dFluxdX
void applySingleEquationNeumannBC(const T_Scalar &bFlux, const int v) const
void applySingleEquationDirichletBC(const FloatValEvaluator< T_Scalar > &bValue, const int v) const
const MultiField::ArrayIndex _xIndex
Definition: Field.h:14
const Field & _fluxField
const Field & _areaField
XArray & _rFlux
Definition: Mesh.h:49
void setCoeffR(const int f, const OffDiag &c)
OffDiag & getCoeff10(const int np)
Definition: CRMatrix.h:131
const Field & _areaMagField
Array< T_Scalar > TArray
Definition: BatteryPC_BCS.h:28
Array< X > XArray
Definition: BatteryPC_BCS.h:42
const VectorT3Array & _faceArea
const Field & _varField
CCAssembler & _assembler
Array< VectorT3 > VectorT3Array
Definition: BatteryPC_BCS.h:43
void setCoeffL(const int f, const OffDiag &c)
DiagArray & _dRdXDiag
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
XArray & _flux
Array< int > IntArray
Definition: BatteryPC_BCS.h:29
BatteryPC_BCS(const StorageSite &faces, const Mesh &mesh, const GeomFields &geomFields, Field &varField, Field &fluxField, MultiFieldMatrix &matrix, MultiField &xField, MultiField &rField)
Definition: BatteryPC_BCS.h:46
Array< Diag > DiagArray
Definition: BatteryPC_BCS.h:39
void applySingleEquationNeumannBC(const int f, const T_Scalar &specifiedFlux, const int v) const
OffDiag & getCoeff01(const int np)
Definition: CRMatrix.h:126
CCMatrix & _dRdX
Definition: Array.h:14
void setBoundary(const int nr)
Definition: CRMatrix.h:1056
void applySingleEquationDirichletBC(int f, const T_Scalar &bValue, const int v) const
Definition: BatteryPC_BCS.h:77
FluxJacobianMatrix< Diag, X > FMatrix
Definition: BatteryPC_BCS.h:36
DiagonalMatrix< Diag, X > BBMatrix
Definition: BatteryPC_BCS.h:37
const TArray & _faceAreaMag
int getCount() const
Definition: StorageSite.h:39
CRMatrix< Diag, OffDiag, X > CCMatrix
Definition: BatteryPC_BCS.h:33
BBMatrix & _dFluxdFlux
const bool _is2D
const StorageSite & _faces
const CRConnectivity & _faceCells
const IntArray & _ibType
CCMatrix::PairWiseAssembler CCAssembler
Definition: BatteryPC_BCS.h:34
Vector< T_Scalar, 3 > VectorT3
Definition: BatteryPC_BCS.h:31