Memosa-FVM  0.2
KineticBoundaryConditions.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 _KINETICBOUNDARYCONDITIONS_H_
6 #define _KINETICBOUNDARYCONDITIONS_H_
7 #include <stdio.h>
8 #include "Mesh.h"
9 #include <vector>
10 #include <cmath>
11 #include "NumType.h"
12 #include "Array.h"
13 #include "Vector.h"
14 #include "Field.h"
15 #include "StorageSite.h"
16 #include "CRConnectivity.h"
17 #include "MultiFieldMatrix.h"
18 #include "CRMatrix.h"
19 #include "FluxJacobianMatrix.h"
20 #include "DiagonalMatrix.h"
21 
22 #include "StressTensor.h"
23 template<class X,class Diag,class OffDiag>
25 {
26  public :
27 
29 
31 
35 
36  typedef Array<X> XArray;
37  typedef Vector<X,3> VectorX3; //new for esbgk
41 
42 
44  const Mesh& mesh,
45  const GeomFields& geomFields,
46  const Quadrature<X>& quadrature,
47  MacroFields& macroFields,
48  DistFunctFields<X>& dsfPtr):
49 
50  _faces(faces),
51  _cells(mesh.getCells()),
52  _ibType(dynamic_cast<const IntArray&>(geomFields.ibType[_cells])),
53  _quadrature(quadrature),
54  _macroFields(macroFields),
55  _dsfPtr(dsfPtr),
56  _faceCells(mesh.getFaceCells(_faces)),
57  _areaMagField(geomFields.areaMag),
58  _faceAreaMag(dynamic_cast<const TArray&>(_areaMagField[_faces])),
59  _areaField(geomFields.area),
60  _faceArea(dynamic_cast<const VectorT3Array&>(_areaField[_faces]))
61 
62  {}
64 
65  void applyDiffuseWallBC(int f,const VectorX3& WallVelocity,const X& WallTemperature) const
66  {
67 
68  const double pi=_options.pi;
69  const double epsilon=_options.epsilon_ES;
70 
71  const int c0 = _faceCells(f,0);
72  const int c1 = _faceCells(f,1);
73 
74  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
75  return;
76 
77 
78  const int numDirections = _quadrature.getDirCount();
79  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
80  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
81  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
82  const XArray& wts= dynamic_cast<const XArray&>(*_quadrature.dcxyzPtr);
84  XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
85  //XArray& pressure = dynamic_cast<XArray&>(_macroFields.pressure[_cells]);
86  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
87  const X uwall = WallVelocity[0];
88  const X vwall = WallVelocity[1];
89  const X wwall = WallVelocity[2];
90  //cout << "uwall " << uwall << endl;
91  const X Twall = WallTemperature;
92 
93  v[c1][0]=uwall;
94  v[c1][1]=vwall;
95  v[c1][2]=wwall;
96 
97  temperature[c1]=Twall;
98  X Nmr(0.0) ;
99  X Dmr(0.0) ;
100  X incomFlux(0.0);
101  for (int j=0; j<numDirections; j++)
102  {
103  Field& fnd = *_dsfPtr.dsf[j];
104  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
105  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
106  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
107  const X wallV_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
108  const X fwall = 1.0/pow(pi*Twall,1.5)*exp(-(pow(cx[j]-uwall,2.0)+pow(cy[j]-vwall,2.0)+pow(cz[j]-wwall,2.0))/Twall);
109  if (c_dot_en -wallV_dot_en < T_Scalar(epsilon)) //incoming
110  {
111  Dmr = Dmr - fwall*wts[j]*(c_dot_en-wallV_dot_en);
112  incomFlux=incomFlux-dsf[c0]*wts[j]*(c_dot_en -wallV_dot_en);
113  }
114  else
115  {
116  Nmr = Nmr + dsf[c0]*wts[j]*(c_dot_en -wallV_dot_en);
117  }
118  }
119  const X nwall = Nmr/Dmr; // wall number density for initializing Maxwellian
120  density[c1]=nwall;
121  //if (c0==80)cout <<"incoming" << incomFlux <<" outgoing" <<Nmr <<endl;
122  for (int j=0; j<numDirections; j++)
123  {
124  Field& fnd = *_dsfPtr.dsf[j];
125  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
126  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
127  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
128  const X wallV_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
129 
130  if (c_dot_en-wallV_dot_en < T_Scalar(epsilon))
131  {
132  dsf[c1] = nwall/pow(pi*Twall,1.5)*exp(-(pow(cx[j]-uwall,2.0)+pow(cy[j]-vwall,2.0)+pow(cz[j]-wwall,2.0))/Twall);
133  //dsf[c0]=dsf[c1]; // change value of fluid boundary-cell
134  }
135  else
136  dsf[c1]=dsf[c0];
137  }
138 
139 
140 
141  }
142 
143 void applyDiffuseWallBC(const VectorX3& bVelocity,const X& bTemperature) const
144  {
145  for (int i=0; i<_faces.getCount();i++)
146  applyDiffuseWallBC(i,bVelocity,bTemperature);
147  }
148 
149 
150  void applyDiffuseWallBC(const FloatValEvaluator<VectorX3>& bVelocity,const FloatValEvaluator<X>& bTemperature)const
151  {
152  for (int i=0; i<_faces.getCount();i++)
153  applyDiffuseWallBC(i,bVelocity[i],bTemperature[i]);
154 
155  }
156 
157  // Real wall with momentum accomodation coefficient
158  void applyRealWallBC(int f,const VectorX3& WallVelocity,const X& WallTemperature,const X& accommodationCoefficient,const vector<int>& vecReflection) const
159  {
160 
161  const double pi=_options.pi;
162  //const double epsilon=_options.epsilon_ES;
163 
164  const int c0 = _faceCells(f,0);
165  const int c1 = _faceCells(f,1);
166 
167  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
168  return;
169 
170 
171  const int numDirections = _quadrature.getDirCount();
172  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
173  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
174  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
175  const XArray& wts= dynamic_cast<const XArray&>(*_quadrature.dcxyzPtr);
177  XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
178  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
179  const X uwall = WallVelocity[0];
180  const X vwall = WallVelocity[1];
181  const X wwall = WallVelocity[2];
182  const X Twall = WallTemperature;
183  const X alpha = accommodationCoefficient;
184  X m1alpha=1.0-alpha;
185  v[c1][0]=uwall;
186  v[c1][1]=vwall;
187  v[c1][2]=wwall;
188 
189  temperature[c1]=Twall;
190  X Nmr(0.0) ;
191  X Dmr(0.0) ;
192  X incomFlux(0.0);
193  for (int j=0; j<numDirections; j++)
194  {
195  Field& fnd = *_dsfPtr.dsf[j];
196  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
197  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
198  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
199  const X wallV_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
200  const X fwall = 1.0/pow(pi*Twall,1.5)*exp(-(pow(cx[j]-uwall,2.0)+pow(cy[j]-vwall,2.0)+pow(cz[j]-wwall,2.0))/Twall);
201  if (c_dot_en -wallV_dot_en < T_Scalar(0.0)) //incoming
202  {
203  Dmr = Dmr - fwall*wts[j]*(c_dot_en-wallV_dot_en);
204  incomFlux=incomFlux-dsf[c0]*wts[j]*(c_dot_en-wallV_dot_en);
205  }
206  else
207  {
208  Nmr = Nmr + dsf[c0]*wts[j]*(c_dot_en-wallV_dot_en);
209  }
210  }
211  const X nwall = Nmr/Dmr; // wall number density for initializing Maxwellian
212  density[c1]=nwall;
213  //if (c0==80)cout <<"incoming " << incomFlux <<" outgoing " <<Nmr << " dens " << nwall<< endl;
214  //update f in boundary cell =alpha*f_wall+(1-alpha)*f_reflection
215  //c.en-vwall.en=vwall.en-c_incident.en
216 
217  for (int j=0; j<numDirections; j++)
218  {
219  Field& fnd = *_dsfPtr.dsf[j];
220  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
221  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
222  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
223  const X wallV_dot_en = uwall*en[0]+vwall*en[1]+wwall*en[2];
224 
225  // needed for method 1
226  /*
227  const int N2 = _quadrature.getNthetaCount();
228  const int N3 = _quadrature.getNphiCount();
229  const X dcx = _quadrature.get_dcx();
230  const X dcy = _quadrature.get_dcy();
231  const X dcz = _quadrature.get_dcz();
232  */
233  if (c_dot_en-wallV_dot_en < T_Scalar(0.0))
234  {
235  /*
236  const X cx_incident = cx[j] - 2.0*(c_dot_en-wallV_dot_en)*en[0];
237  const X cy_incident = cy[j] - 2.0*(c_dot_en-wallV_dot_en)*en[1];
238  const X cz_incident = cz[j] - 2.0*(c_dot_en-wallV_dot_en)*en[2];
239 
240  //method 1
241  const X i_incident = int((cx_incident-cx[0])/dcx+0.5);
242  const X j_incident = int((cy_incident-cy[0])/dcy+0.5);
243  const X k_incident = int((cz_incident-cz[0])/dcz+0.5);
244  const int direction_incident = k_incident+N3*j_incident+N3*N2*i_incident;
245 
246  //method 2
247  int direction_incident=0;
248  X Rdotprod=1e54;
249  X dotprod=0.0;
250  for (int js=0; js<numDirections; js++){
251  dotprod=pow(cx_incident-cx[js],2)+pow(cy_incident-cy[js],2)+pow(cz_incident-cz[js],2);
252  if (dotprod< Rdotprod){
253  Rdotprod =dotprod;
254  direction_incident=js;}
255  }
256 
257  */
258  const int direction_incident = vecReflection[j];
259  Field& fndi = *_dsfPtr.dsf[direction_incident];
260  const XArray& dsfi = dynamic_cast<const XArray&>(fndi[_cells]);
261 
262  dsf[c1] = alpha*nwall/pow(pi*Twall,1.5)*exp(-(pow(cx[j]-uwall,2.0)+pow(cy[j]-vwall,2.0)+pow(cz[j]-wwall,2.0))/Twall)+m1alpha*dsfi[c0]; //write into boundary;
263  //dsf[c0]=dsf[c1]; //write into boundary cell
264  }
265  else
266  dsf[c1]=dsf[c0];
267  }
268 
269 
270 
271  }
272 
273  void applyRealWallBC(const VectorX3& bVelocity,const X& bTemperature,const X& accomCoeff,const vector<int>& vecReflection) const
274  {
275  for (int i=0; i<_faces.getCount();i++)
276  applyRealWallBC(i,bVelocity,bTemperature,accomCoeff,vecReflection);
277  }
278 
279 
280  void applyRealWallBC(const FloatValEvaluator<VectorX3>& bVelocity,const FloatValEvaluator<X>& bTemperature,const FloatValEvaluator<X>& accomCoeff,const vector<int>& vecReflection) const
281  {
282  for (int i=0; i<_faces.getCount();i++)
283  applyRealWallBC(i,bVelocity[i],bTemperature[i],accomCoeff[i],vecReflection);
284 
285  }
286 
287  void applySpecularWallBC(int f,const vector<int>& vecReflection) const
288  {
289 
290  const int c0 = _faceCells(f,0); //interior
291  const int c1 = _faceCells(f,1); //boundary cell
292 
293  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
294  return;
295 
296  const int numDirections = _quadrature.getDirCount();
297  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
298  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
299  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
300 
301  for (int j=0; j<numDirections; j++)
302  {
303  // Find incident molecule directions
304  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
305  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
306 
307  Field& fndw = *_dsfPtr.dsf[j];
308  XArray& dsfw = dynamic_cast<XArray&>(fndw[_cells]);
309  if(c_dot_en < T_Scalar(0.0)) //incoming molecules to interior
310  {
311  const int direction_incident = vecReflection[j];
312  Field& fnd = *_dsfPtr.dsf[direction_incident];
313  const XArray& dsf = dynamic_cast<const XArray&>(fnd[_cells]);
314  dsfw[c1] = dsf[c0]; //write into boundary
315  }
316  else{
317  dsfw[c1]=dsfw[c0];}
318  }
319 
320 
321  }
322 
323  void applySpecularWallBC(const vector<int>& vecReflection) const
324  {
325  for (int i=0; i<_faces.getCount();i++){
326  applySpecularWallBC(i,vecReflection);
327  // applySpecularWallBC_Cartesian(i);
328  }
329 
330  }
331 
333  {
334 
335  const int c0 = _faceCells(f,0); //interior
336  const int c1 = _faceCells(f,1); //boundary cell
337 
338  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
339  return;
340 
341  const int numDirections = _quadrature.getDirCount();
342  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
343  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
344  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
345 
346  const int N2 = _quadrature.getNthetaCount();
347  const int N3 = _quadrature.getNphiCount();
348  const X dcx = _quadrature.get_dcx();
349  const X dcy = _quadrature.get_dcy();
350  const X dcz = _quadrature.get_dcz();
351 
352  for (int j=0; j<numDirections; j++)
353  {
354  // Find incident molecule directions
355  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
356  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
357 
358  Field& fndw = *_dsfPtr.dsf[j];
359  XArray& dsfw = dynamic_cast<XArray&>(fndw[_cells]);
360  if(c_dot_en < T_Scalar(0.0)) //incoming molecules to interior
361  {
362 
363  const X cx_incident = cx[j] - 2.0*c_dot_en*en[0];
364  const X cy_incident = cy[j] - 2.0*c_dot_en*en[1];
365  const X cz_incident = cz[j] - 2.0*c_dot_en*en[2];
366 
367  const X i_incident = int((cx_incident-cx[0])/dcx+0.5);
368  const X j_incident = int((cy_incident-cy[0])/dcy+0.5);
369  const X k_incident = int((cz_incident-cz[0])/dcz+0.5);
370  const int direction_incident = k_incident+N3*j_incident+N3*N2*i_incident;
371 
372  Field& fnd = *_dsfPtr.dsf[direction_incident];
373  const XArray& dsf = dynamic_cast<const XArray&>(fnd[_cells]);
374 
375  dsfw[c1] = dsf[c0]; //write into boundary
376 
377  }
378  else{
379  dsfw[c1]=dsfw[c0];}
380  }
381 
382 
383  }
384 
385  void applyZeroGradientBC(int f) const
386  {
387  const int c0 = _faceCells(f,0);
388  const int c1 = _faceCells(f,1);
389 
390  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
391  return;
392 
393  const int numDirections = _quadrature.getDirCount();
394 
395  for (int j=0; j<numDirections; j++)
396  {
397  Field& fnd = *_dsfPtr.dsf[j];
398  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
399  dsf[c1]=dsf[c0];
400  }
401  }
402  void applyZeroGradientBC() const
403  {
404  for (int i=0; i<_faces.getCount();i++)
406  }
407 
408  void applyPressureInletBC(int f,const X& inletTemperature,const X& inletPressure) const
409  {
410 
411  const double pi=_options.pi;
412  const int c0 = _faceCells(f,0);
413  const int c1 = _faceCells(f,1);
414 
415  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
416  return;
417 
418 
419  const int numDirections = _quadrature.getDirCount();
420  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
421  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
422  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
423  const XArray& wts = dynamic_cast<const XArray&>(*_quadrature.dcxyzPtr);
424  XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
425  XArray& pressure = dynamic_cast<XArray&>(_macroFields.pressure[_cells]);
426  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
428 
429 
430  X uwallnew = 0.0;
431 
432  const X Tin = inletTemperature;
433  const X Pin = inletPressure;
434  const X nin = Pin/Tin; // wall number density for initializing Maxwellian
435 
436  //store boundary values
437  temperature[c1]=inletTemperature;
438  pressure[c1]=inletPressure;
439  density[c1]=nin;
440  v[c1][0]=0.0;
441  v[c1][1]=0.0;
442  v[c1][2]=0.0;
443 
444  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
445 
446 
447  //update velocity
448  for (int j=0; j<numDirections; j++)
449  {
450  Field& fnd = *_dsfPtr.dsf[j];
451  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
452  dsf[c1] = nin/pow(pi*Tin,1.5)*exp(-(pow(cx[j]-v[c1][0],2.0)+pow(cy[j]-v[c1][1],2.0)+pow(cz[j]-v[c1][2],2.0))/Tin);
453 
454  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
455 
456  if (abs(en[0]) == T_Scalar(1.0))
457  {
458  if( c_dot_en > T_Scalar(0.0))
459  {
460  uwallnew=uwallnew+cx[j]*dsf[c0]*wts[j];
461  }
462  else {uwallnew=uwallnew+cx[j]*dsf[c1]*wts[j];}
463  }
464  else if (abs(en[1]) == T_Scalar(1.0))
465  {
466  if( c_dot_en > T_Scalar(0.0))
467  {
468  uwallnew=uwallnew+cy[j]*dsf[c0]*wts[j];
469  }
470  else {uwallnew=uwallnew+cy[j]*dsf[c1]*wts[j];}
471  }
472  else if (abs(en[2]) == T_Scalar(1.0))
473  {
474  if( c_dot_en > T_Scalar(0.0))
475  {
476  uwallnew=uwallnew+cz[j]*dsf[c0]*wts[j];
477  }
478  else {uwallnew=uwallnew+cz[j]*dsf[c1]*wts[j];}
479  }
480  }
481  /*
482  if (abs(en[0]) == T_Scalar(1.0))
483  v[c1][0]=uwallnew/nin;
484  else if (abs(en[1]) == T_Scalar(1.0)) //incoming {vwallnew=vwallnew+cy[j]*dsf[c1]*wts[j];}
485  v[c1][1]=uwallnew/nin;
486  else if(abs(en[2]) == T_Scalar(1.0))
487  v[c1][2]=uwallnew/nin;//uwall=uwall+relax*(uwallnew-uwall);
488  */
489 
490 
491  //update f
492  for (int j=0; j<numDirections; j++)
493  {
494  Field& fnd = *_dsfPtr.dsf[j];
495  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
496  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
497  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
498  if (c_dot_en< T_Scalar(0.0))
499  {
500  dsf[c1] = nin/pow(pi*Tin,1.5)*exp(-(pow(cx[j]-v[c1][0],2.0)+pow(cy[j]-v[c1][1],2.0)+pow(cz[j]-v[c1][2],2.0))/Tin);
501  // dsf[c0]=dsf[c1];// change value of fluid boundary-cell
502  }
503  else{dsf[c1]=dsf[c0];}//outgoing
504 
505  }
506 
507 }
508 
509 
510 
511 
512  void applyPressureInletBC(const FloatValEvaluator<X>& bTemperature,const FloatValEvaluator<X>& bPresssure) const
513  {
514  for (int i=0; i<_faces.getCount();i++)
515  applyPressureInletBC(i,bTemperature[i],bPresssure[i]);
516 
517  }
518 
519 
520  // velocity inlet given temperature and mass flow rate
521 
522  void applyInletBC(int f,const VectorX3& InletVelocity,const X& InletTemperature,const X& InletMdot,const vector<int>& vecReflection) const
523  {
524 
525  const double pi=_options.pi;
526  //const double epsilon=_options.epsilon_ES;
527 
528  const int c0 = _faceCells(f,0);
529  const int c1 = _faceCells(f,1);
530 
531  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
532  return;
533 
534 
535  const int numDirections = _quadrature.getDirCount();
536  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
537  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
538  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
539  const XArray& wts= dynamic_cast<const XArray&>(*_quadrature.dcxyzPtr);
541  XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
542  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
543  const X uin = InletVelocity[0];
544  const X vin = InletVelocity[1];
545  const X win = InletVelocity[2];
546  const X Tin = InletTemperature;
547  const X mdot = InletMdot;
548 
549  v[c1][0]=uin;
550  v[c1][1]=vin;
551  v[c1][2]=win;
552 
553  temperature[c1]=Tin;
554  X Nmr(0.0) ;
555  X Dmr(0.0);
556  const X rho_init=_options["rho_init"];
557  const X T_init= _options["T_init"];
558  const X R=8314.0/_options["molecularWeight"];
559  const X u_init=pow(2.0*R*T_init,0.5);
560  // find the number density corressponding to the inlet Maxwellian
561  for (int j=0; j<numDirections; j++)
562  {
563  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
564  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
565  const X fwall = 1.0/pow(pi*Tin,1.5)*exp(-(pow(cx[j]-uin,2.0)+pow(cy[j]-vin,2.0)+pow(cz[j]-win,2.0))/Tin);
566  if (c_dot_en < T_Scalar(0.0)){Dmr = Dmr + fwall*wts[j]*c_dot_en;}
567  Nmr=mdot/(rho_init*u_init);
568 
569  }
570  const X nin = Nmr/Dmr; // wall number density for initializing Maxwellian
571  density[c1]=nin;
572 
573  for (int j=0; j<numDirections; j++)
574  {
575  Field& fnd = *_dsfPtr.dsf[j];
576  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
577  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
578  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
579 
580  if (c_dot_en < T_Scalar(0.0))
581  {
582  const int direction_incident = vecReflection[j];
583  Field& fndi = *_dsfPtr.dsf[direction_incident];
584  const XArray& dsfi = dynamic_cast<const XArray&>(fndi[_cells]);
585 
586  dsf[c1] = nin/pow(pi*Tin,1.5)*exp(-(pow(cx[j]-uin,2.0)+pow(cy[j]-vin,2.0)+pow(cz[j]-win,2.0))/Tin)+dsfi[c0]; //inlet Maxwellian +reflected
587  }
588  else
589  dsf[c1]=dsf[c0];
590  }
591 
592  }
593  void applyInletBC(const VectorX3& bVelocity,const X& bTemperature,const X& Mdot,const vector<int>& vecReflection) const
594  {
595  for (int i=0; i<_faces.getCount();i++)
596  applyInletBC(i,bVelocity,bTemperature,Mdot,vecReflection);
597  }
598 
599 
600  void applyInletBC(const FloatValEvaluator<VectorX3>& bVelocity,const FloatValEvaluator<X>& bTemperature,const FloatValEvaluator<X>& Mdot,const vector<int>& vecReflection) const
601  {
602  for (int i=0; i<_faces.getCount();i++)
603  applyInletBC(i,bVelocity[i],bTemperature[i],Mdot[i],vecReflection);
604 
605  }
606 
607 
608 
609 
610  //outlet Boundary Condition
611  void applyPressureOutletBC(int f,const X& outletTemperature,const X& outletPressure) const
612  {
613 
614  const double pi=_options.pi;
615  const int c0 = _faceCells(f,0);
616  const int c1 = _faceCells(f,1);
617 
618  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
619  return;
620 
621  const int numDirections = _quadrature.getDirCount();
622  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
623  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
624  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
625  XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
627  XArray& pressure = dynamic_cast<XArray&>(_macroFields.pressure[_cells]);
628  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
629 
630  // X Tout = outletTemperature;
631  const X Pout = outletPressure;
632  X Pcell= pressure[c0];
633  X gamma =_options.SpHeatRatio;
634  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
635  X nout =density[c0];
636 
637  if (Pcell > Pout){
638  const X avel2 =gamma*Pcell/density[c0]; //velcotiy of sound square
639  nout =density[c0]-(Pcell-Pout)/avel2;
640  X ubulk=pow(pow(v[c0][0],2.0)+pow(v[c0][1],2.0)+pow(v[c0][2],2.0),0.5);
641  X ucoeff=1.0/ubulk*(ubulk+(Pcell-Pout)/(pow(2.0*avel2,0.5)*density[c0]));
642  if(abs(en[0])==T_Scalar(1.0))
643  v[c1][0] = v[c0][0]*ucoeff;
644  //v[c1][0]=v[c0][0]+(pressure[c0]-Pout)/(pow(2.0*avel2,0.5)*density[c0]); //exit velocity
645  else if(abs(en[1])==T_Scalar(1.0))
646  v[c1][1] = v[c0][1]*ucoeff;
647  else if(abs(en[2])==T_Scalar(1.0))
648  v[c1][2] = v[c0][2]*ucoeff;
649 
650  density[c1]=nout; pressure[c1]=Pout; //update macroPr
651  temperature[c1]=Pout/nout;
652  }
653  else{
654 
655  density[c1]=density[c0];
656  pressure[c1]=pressure[c0];
657  temperature[c1]=temperature[c0];
658 
659  }
660  for (int j=0; j<numDirections; j++)
661  {
662  Field& fnd = *_dsfPtr.dsf[j];
663  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
664 
665  const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
666  if (c_dot_en < T_Scalar(0.0))
667  {
668  dsf[c1] = nout/pow(pi*temperature[c1],1.5)*exp(-(pow(cx[j]-v[c1][0],2.0)+pow(cy[j]-v[c1][1],2.0)+pow(cz[j]-v[c1][2],2.0))/temperature[c1]);
669  // dsf[c0]=dsf[c1];// change value of fluid boundary-cell
670  }
671  else{dsf[c1]=dsf[c0];}
672 
673  }
674 
675 
676 }
677 
678  void applyPressureOutletBC(const X& bTemperature, const X& bPressure) const
679  {
680  for (int i=0; i<_faces.getCount();i++)
681  applyPressureOutletWallBC(i,bTemperature,bPressure);
682  }
683 
684 
685  void applyPressureOutletBC(const FloatValEvaluator<X>& bTemperature,const FloatValEvaluator<X>& bPresssure) const
686  {
687  for (int i=0; i<_faces.getCount();i++)
688  applyPressureOutletBC(i,bTemperature[i],bPresssure[i]);
689 
690  }
691 
692 
693  void applyNSInterfaceBC( )const
694 //const FloatValEvaluator<X>& bTemperature,const FloatValEvaluator<X>& bPressure,const FloatValEvaluator<VectorX3>& bVelocity, const FloatValEvaluator<VectorX3>& bStress) const
695  {
696 
697  for (int i=0; i<_faces.getCount();i++)
698  applyNSInterfaceBC(i); //,bTemperature[i],bPressure[i],bVelocity[i],bStress[i]);
699 
700 
701 
702  }
703 
704 
705 
706  void applyNSInterfaceBC(int f)const //X& inletTemperature,const X& inletPressure, const VectorX3& inletVelocity, const VectorX3&tau) const
707  //StressTensor<X>&tau) const
708  {
709 
710  const double pi=_options.pi;
711  const int c0 = _faceCells(f,0);
712  const int c1 = _faceCells(f,1);
713 
714  if (_ibType[c0] != Mesh::IBTYPE_FLUID)
715  return;
716 
717 
718  const int numDirections = _quadrature.getDirCount();
719  const XArray& cx = dynamic_cast<const XArray&>(*_quadrature.cxPtr);
720  const XArray& cy = dynamic_cast<const XArray&>(*_quadrature.cyPtr);
721  const XArray& cz = dynamic_cast<const XArray&>(*_quadrature.czPtr);
722 
723  //XArray& density = dynamic_cast<XArray&>(_macroFields.density[_cells]);
724  //XArray& pressure = dynamic_cast<XArray&>(_macroFields.pressure[_cells]);
725  XArray& temperature = dynamic_cast<XArray&>(_macroFields.temperature[_cells]);
726  //VectorX3Array& v = dynamic_cast<VectorX3Array&>(_macroFields.velocity[_cells]);
727 
728  XArray& viscosity = dynamic_cast<XArray&>(_macroFields.viscosity[_cells]);
729 
730 
732  XArray& IntPress = dynamic_cast<XArray&>(_macroFields.InterfacePressure[_faces]);
733  //XArray& IntDens = dynamic_cast<XArray&>(_macroFields.InterfaceDensity[_faces]);
735 
736  const X Tin = temperature[c0];
737  const X Pin = IntPress[f];
738  const X nin = Pin/Tin; // wall number density for initializing Maxwellian
739 
740 
741  const X u_in=IntVel[f][0];
742  const X v_in=IntVel[f][1];
743  const X w_in=IntVel[f][2];
744 
745  const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
746 
747  // Extra for CE expression
748  const X rho_init=_options["rho_init"];
749  const X T_init= _options["T_init"];
750  const X R=8314.0/_options["molecularWeight"];
751  const X nondim_length=_options["nonDimLt"];
752  const X mu0=rho_init*R* T_init*nondim_length/pow(2*R* T_init,0.5);
753 
754  //update f to Maxwellian
755  for (int j=0; j<numDirections; j++)
756  {
757  Field& fnd = *_dsfPtr.dsf[j];
758  XArray& dsf = dynamic_cast< XArray&>(fnd[_cells]);
759  //const VectorT3 en = _faceArea[f]/_faceAreaMag[f];
760  //const X c_dot_en = cx[j]*en[0]+cy[j]*en[1]+cz[j]*en[2];
761  //if (c_dot_en< T_Scalar(0.0))
762  {
763  //cout << "nin " <<nin <<endl;
764  dsf[c1] = nin/pow(pi*Tin,1.5)*exp(-(pow(cx[j]-u_in,2.0)+pow(cy[j]-v_in,2.0)+pow(cz[j]-w_in,2.0))/Tin)
765  *(1-viscosity[c0]/mu0/(nin*pow(Tin,2.0))*(pow(cx[j]-u_in,2.0)*tau[f][0]+pow(cy[j]-v_in,2.0)*tau[f][1]+pow(cz[j]-w_in,2.0)*tau[f][2])
766  +2.0*(cx[j]-u_in)*(cy[j]-v_in)*tau[f][3]+2.0*(cy[j]-v_in)*(cz[j]-w_in)*tau[f][4]+2.0*(cz[j]-w_in)*(cx[j]-u_in)*tau[f][5]); //update f to ChapmannEnskog
767  }
768  //else{dsf[c1]=dsf[c0];}//outgoing
769 
770  }
771  //update f to ChapmannEnskog
772 
773 
774 //dsf[c1]=dsf[c1]*(1-2*cx[j]*cy[j]*slopeL*viscosity[c]/mu0) //velocity tangential only
775 //C2=pow(cx[j]-u_in,2.0)+pow(cy[j]-v_in,2.0)+pow(cz[j]-w_in,2.0)
776 //dsf[c1]=dsf[c1]*(1+viscosity[c1]/(mu0*Pr*nin*pow(Tin,2.0))*((cx[j]-u_in)*dtbdx+(cy[j]-v_in)*dtbdy+(cz[j]-w_in)*dtbdz)*(C2-2.5))
777 //temperature difference too
778  }
779 
780 
781 
782 
783  protected:
784 
797 };
798 
799 #endif
void applyDiffuseWallBC(const VectorX3 &bVelocity, const X &bTemperature) const
#define epsilon
Definition: Mesh.cpp:17
void applyPressureOutletBC(int f, const X &outletTemperature, const X &outletPressure) const
void applyRealWallBC(const VectorX3 &bVelocity, const X &bTemperature, const X &accomCoeff, const vector< int > &vecReflection) const
void applyInletBC(int f, const VectorX3 &InletVelocity, const X &InletTemperature, const X &InletMdot, const vector< int > &vecReflection) const
T get_dcy() const
Definition: Quadrature.h:61
int getNphiCount() const
Definition: Quadrature.h:59
Definition: Field.h:14
void applyDiffuseWallBC(int f, const VectorX3 &WallVelocity, const X &WallTemperature) const
TArray * cyPtr
Definition: Quadrature.h:42
Definition: Mesh.h:49
int getDirCount() const
Definition: Quadrature.h:56
Field InterfaceVelocity
Definition: MacroFields.h:39
void applyPressureOutletBC(const X &bTemperature, const X &bPressure) const
void applyPressureInletBC(int f, const X &inletTemperature, const X &inletPressure) const
void applyRealWallBC(int f, const VectorX3 &WallVelocity, const X &WallTemperature, const X &accommodationCoefficient, const vector< int > &vecReflection) const
TArray * dcxyzPtr
Definition: Quadrature.h:52
Field InterfacePressure
Definition: MacroFields.h:40
KineticModelOptions< X > _options
KineticBoundaryConditions(const StorageSite &faces, const Mesh &mesh, const GeomFields &geomFields, const Quadrature< X > &quadrature, MacroFields &macroFields, DistFunctFields< X > &dsfPtr)
TArray * czPtr
Definition: Quadrature.h:47
Field viscosity
Definition: MacroFields.h:20
Field temperature
Definition: MacroFields.h:22
void applySpecularWallBC(int f, const vector< int > &vecReflection) const
void applyPressureOutletBC(const FloatValEvaluator< X > &bTemperature, const FloatValEvaluator< X > &bPresssure) const
void applyInletBC(const VectorX3 &bVelocity, const X &bTemperature, const X &Mdot, const vector< int > &vecReflection) const
TArray * cxPtr
Definition: Quadrature.h:37
T get_dcx() const
Definition: Quadrature.h:60
NumTypeTraits< X >::T_Scalar T_Scalar
void applyInletBC(const FloatValEvaluator< VectorX3 > &bVelocity, const FloatValEvaluator< X > &bTemperature, const FloatValEvaluator< X > &Mdot, const vector< int > &vecReflection) const
const DistFunctFields< X > & _dsfPtr
void applyRealWallBC(const FloatValEvaluator< VectorX3 > &bVelocity, const FloatValEvaluator< X > &bTemperature, const FloatValEvaluator< X > &accomCoeff, const vector< int > &vecReflection) const
Field velocity
Definition: MacroFields.h:15
const Quadrature< X > & _quadrature
Field pressure
Definition: MacroFields.h:19
Field InterfaceStress
Definition: MacroFields.h:41
std::vector< Field * > dsf
int getNthetaCount() const
Definition: Quadrature.h:58
int getCount() const
Definition: StorageSite.h:39
void applyPressureInletBC(const FloatValEvaluator< X > &bTemperature, const FloatValEvaluator< X > &bPresssure) const
T get_dcz() const
Definition: Quadrature.h:62
void applySpecularWallBC(const vector< int > &vecReflection) const
void applyDiffuseWallBC(const FloatValEvaluator< VectorX3 > &bVelocity, const FloatValEvaluator< X > &bTemperature) const
Array< StressTensorX6 > StressTensorArray
Field density
Definition: MacroFields.h:21
KineticModelOptions< X > & getOptions()
void applySpecularWallBC_Cartesian(int f) const