PlasCom2  1.0
XPACC Multi-physics simluation application
ViscidUtil.H
Go to the documentation of this file.
1 #ifndef __VISCID_UTIL_H__
2 #define __VISCID_UTIL_H__
3 
4 #include "PlasCom2.H"
5 #include "PCPPCommUtil.H"
6 #include "PCPPIntervalUtils.H"
7 #include "PCPPReport.H"
8 
9 namespace viscid {
10  namespace util {
11 
13  // Input:
14  // inInterval: (xStart xEnd yStart yEnd zStart zEnd)
15  // bufferSize: (numX numY numZ)
16  // stateBuffer: [ *rho *rhoV *rhoE *scalarVars ]
17  //
18  // Output:
19  // tvBuffer: [mu lambda kappa]
20  //
21  // simple implementation, ported from PlasComCM
22  int ComputeTVBufferPower(const pcpp::IndexIntervalType &regionInterval,
23  const std::vector<size_t> &bufferSize,
24  const double * temperatureBuffer,
25  std::vector<double *> &tvBuffer,
26  const double beta,
27  const double power,
28  const double bulkViscFac,
29  const double specificHeat,
30  const double prandtlNumber);
31 
32  // Fortran-like interfaces
33  // Uses Fortran Kernels
34  // MJA TBD, no yet implemented
35  int ComputeTVBuffer(const int *numDimPtr,
36  const size_t *bufferSize,
37  const size_t *numPointsPtr,
38  const size_t *bufferInterval,
39  const double *rhoBuffer,
40  const double *rhoVBuffer,
41  const double *rhoEBuffer,
42  double *pressureBuffer,
43  double *tempBuffer,
44  double *rhom1Buffer,
45  double *velBuffer);
46 
47  // Fortran-like interfaces
48  int ComputeTauBuffer(const pcpp::IndexIntervalType &regionInterval,
49  const std::vector<size_t> &bufferSize,
50  int gridType,
51  const std::vector<double> &gridMetrics,
52  const std::vector<double> &gridJacobian,
53  const double &Re,
54  const std::vector<double *> &tvBuffers,
55  const std::vector<double *> &velGradBuffers,
56  std::vector<double *> &tauBuffers);
57 
58  // Fortran-like interfaces
59 // int ComputeHeatFluxBuffer(const pcpp::IndexIntervalType &regionInterval,
60 // const std::vector<size_t> &bufferSize,
61 // const std::vector<double> &gridMetrics,
62 // const double &gridJacobian,
63 // const double &Re,
64 // const std::vector<double *> &tvBuffers,
65 // const std::vector<double *> &temperatureGradBuffers,
66 // std::vector<double *> &heatFluxBuffers);
67 
68 
69  int ComputeHeatFluxBuffer(const pcpp::IndexIntervalType &regionInterval,
70  const std::vector<size_t> &bufferSize,
71  int gridType,
72  const std::vector<double> &gridMetrics,
73  const std::vector<double> &gridJacobian,
74  const double &Re,
75  const std::vector<double *> &tvBuffers,
76  const std::vector<double *> &temperatureGradBuffers,
77  std::vector<double *> &heatFluxBuffers);
78 
79  // initialization for Poiseulle problems
80  //template<typename GridType,typename StateType,typename BoundaryType>
81  template<typename GridType,typename StateType>
82  int InitializePoiseuille(const GridType &inGrid,StateType &inState, StateType &inParamState,
83  const std::vector<double> &inParams,int threadId,
84  std::ostream *messageStream = NULL)
85  {
86 
87  if(!messageStream)
88  messageStream = &std::cout;
89 
90  double inletX = 0.0; // inlet x coordinate
91  double inletY = 0.0; // inlet y coordinate
92  double inletZ = 0.0; // inlet z coordinate
93  double deltaP = .01; // pressure differential across pipe length
94 
95  int numParams = inParams.size();
96  if(numParams > 0)
97  deltaP = inParams[0];
98  if(numParams > 1)
99  inletX = inParams[1];
100  if(numParams > 2)
101  inletY = inParams[2];
102 
103 
104  size_t numPointsBuffer = inGrid.BufferSize();
105  const std::vector<size_t> &gridSizes(inGrid.GridSizes());
106  const std::vector<size_t> &bufferSizes(inGrid.BufferSizes());
107  const pcpp::IndexIntervalType &partitionInterval(inGrid.PartitionInterval());
108  const pcpp::IndexIntervalType &partitionBufferInterval(inGrid.PartitionBufferInterval());
109  int numDim = gridSizes.size();
110  const std::vector<double> &dX(inGrid.DX());
111  const std::vector<double> &readGridExtent(inGrid.PhysicalExtent());
112 
113  if(numDim > 2 && numParams>3)
114  inletZ = inParams[3];
115 
116  // check on dimensionality
117  int nonDimensionalMode=0;
118  {
119  int paramHandle = inParamState.GetDataIndex("nonDimensional");
120  if(paramHandle >= 0){
121  const pcpp::field::dataset::DataBufferType &paramData(inParamState.Field(paramHandle));
122  const int *paramPtr = paramData.Data<int>();
123  nonDimensionalMode = *paramPtr;
124  } else {
125  nonDimensionalMode = 0;
126  }
127  }
128 
129  // get reference conditions
130  double *gammaPtr = inParamState.template GetFieldBuffer<double>("gamma");
131  double *rhoRefPtr = inParamState.template GetFieldBuffer<double>("refRho");
132  double *refLengthPtr = inParamState.template GetFieldBuffer<double>("refLength");
133  double *presRefPtr = inParamState.template GetFieldBuffer<double>("refPressure");
134  double *tempRefPtr = inParamState.template GetFieldBuffer<double>("refTemperature");
135 
136  double gamma = *gammaPtr;
137  double refLength = *refLengthPtr;
138  double refRho = *rhoRefPtr;
139  double refPressure = *presRefPtr;
140  double refTemperature = *tempRefPtr;
141  double sndSpdRef = sqrt(gamma*refPressure/refRho);
142 
143  // adjust input parameters
144  if(nonDimensionalMode == 1) {
145  inletX /= refLength;
146  inletY /= refLength;
147  inletZ /= refLength;
148  } else if (nonDimensionalMode ==2) {
149  inletX /= refLength;
150  inletY /= refLength;
151  inletZ /= refLength;
152  }
153 
154  // determine the flow direction
155  int direction = 0;
156  double xMin = readGridExtent[0];
157  double xMax = readGridExtent[1];
158  double yMin = readGridExtent[2];
159  double yMax = readGridExtent[3];
160  double zMin = 0.;
161  double zMax = 0.;
162  if(numDim > 2 ) {
163  zMin = readGridExtent[4];
164  zMax = readGridExtent[5];
165  }
166  double height = 0.;
167  double length = 0.;
168  double width = 0.;
169 
170  //*messageStream << "xMin " << xMin << std::endl;
171  //*messageStream << "xMax " << xMax << std::endl;
172  //*messageStream << "yMin " << yMin << std::endl;
173  //*messageStream << "yMax " << yMax << std::endl;
174  //*messageStream << "inletX " << inletX << std::endl;
175  //*messageStream << "inletY " << inletY << std::endl;
176  if(inletX == xMin) {
177  // positive X
178  if((inletY == yMin || inletY == yMax) ||
179  ((numDim > 2) && (inletZ == zMin || inletZ == zMax))) {
180  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
181  return(1);
182  }
183  *messageStream << "Initializing Poiseulle flow in the positive X-direction" << std::endl;
184  height = yMax - yMin;
185  length = xMax - xMin;
186  if(numDim > 2)
187  width = zMax - zMin;
188  direction = 1;
189  } else if (inletX == xMax) {
190  // negative X
191  if((inletY == yMin || inletY == yMax) ||
192  ((numDim > 2) && (inletZ == zMin || inletZ == zMax))) {
193  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
194  return(1);
195  }
196  *messageStream << "Initializing Poiseulle flow in the negative X-direction" << std::endl;
197  height = yMax - yMin;
198  length = xMax - xMin;
199  if(numDim > 2)
200  width = zMax - zMin;
201  direction = -1;
202  } else if (inletY == yMin) {
203  // positive Y
204  if((inletX == xMin || inletX == xMax) ||
205  ((numDim > 2) && (inletZ == zMin || inletZ == zMax))) {
206  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
207  return(1);
208  }
209  *messageStream << "Initializing Poiseulle flow in the positive Y-direction" << std::endl;
210  direction = 2;
211  height = xMax - xMin;
212  length = yMax - yMin;
213  if(numDim > 2)
214  width = zMax - zMin;
215  } else if (inletY == yMax) {
216  // negative Y
217  if((inletX == xMin || inletX == xMax) ||
218  ((numDim > 2) && (inletZ == zMin || inletZ == zMax))) {
219  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
220  return(1);
221  }
222  *messageStream << "Initializing Poiseulle flow in the negative Y-direction" << std::endl;
223  height = xMax - xMin;
224  length = yMax - yMin;
225  if(numDim > 2)
226  width = zMax - zMin;
227  direction = -2;
228  } else if (inletZ == zMin) {
229  // positive Z, 3D
230  if(inletX == xMin || inletX == xMax || inletY == yMin || inletY == yMax) {
231  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
232  return(1);
233  }
234  *messageStream << "Initializing 3D Poiseulle flow in the positive Z-direction" << std::endl;
235  height = xMax - xMin;
236  width = yMax - yMin;
237  length = zMax - zMin;
238  direction = 3;
239  } else if (inletZ == zMax) {
240  // negative Z, 3D
241  if(inletX == xMin || inletX == xMax || inletY == yMin || inletY == yMax) {
242  *messageStream << "Invalid inlet specification, point must live on one boundary only! " << std::endl;
243  return(1);
244  }
245  *messageStream << "Initializing 3D Poiseulle flow in the positive Z-direction" << std::endl;
246  height = xMax - xMin;
247  width = yMax - yMin;
248  length = zMax - zMin;
249  direction = -3;
250  } else {
251  *messageStream << "Could not dermine flow direction from inlet specification" << std::endl;
252  return(1);
253  }
254 
255  pcpp::IndexIntervalType gridInterval;
256  gridInterval.InitSimple(gridSizes);
257 
258  *messageStream << "Poiseulle: Grid Sizes: (";
259  pcpp::io::DumpContents(*messageStream,gridSizes,",");
260  *messageStream << ")" << std::endl
261  << "Poiseulle: Partition Interval: ";
262  partitionInterval.PrettyPrint(*messageStream);
263  *messageStream << std::endl << "Poiseulle: Partition Buffer Interval: ";
264  partitionBufferInterval.PrettyPrint(*messageStream);
265  *messageStream << std::endl;
266  *messageStream << "Poiseulle: pipe height " << height << std::endl;
267  if(numDim > 2)
268  *messageStream << "Poiseulle: pipe width " << width << std::endl;
269  *messageStream << "Poiseulle: pipe length " << length << std::endl;
270 
271  const std::vector<double> &coordinateData(inGrid.CoordinateData());
272 
273  int rhoHandle = inState.GetDataIndex("rho");
274  if(rhoHandle < 0)
275  return(1);
276  pcpp::field::dataset::DataBufferType &rhoData(inState.Field(rhoHandle));
277  double *rhoPtr = rhoData.Data<double>();
278  if(!rhoPtr)
279  return(1);
280 
281  int rhoVHandle = inState.GetDataIndex("rhoV");
282  if(rhoVHandle < 0)
283  return(1);
284  pcpp::field::dataset::DataBufferType &rhoVData(inState.Field(rhoVHandle));
285  double *rhoVPtr = rhoVData.Data<double>();
286  if(!rhoVPtr)
287  return(1);
288 
289  int rhoEHandle = inState.GetDataIndex("rhoE");
290  if(rhoEHandle < 0)
291  return(1);
292  pcpp::field::dataset::DataBufferType &rhoEData(inState.Field(rhoEHandle));
293  double *rhoEPtr = rhoEData.Data<double>();
294  if(!rhoPtr)
295  return(1);
296 
297  // Zero entire buffer(s)
298  for(size_t iPoint = 0;iPoint < numPointsBuffer;iPoint++){
299  rhoPtr[iPoint] = 0.0;
300  rhoEPtr[iPoint] = 0.0;
301  }
302  for(int iDim = 0;iDim < numDim;iDim++){
303  size_t dimOffset = iDim*numPointsBuffer;
304  for(size_t iPoint = 0;iPoint < numPointsBuffer;iPoint++)
305  rhoVPtr[iPoint+dimOffset] = 0.0;
306  }
307 
308  // nonDimensional use Re, otherwise calculate mu from the transport model
309  // Re will be set to 1 for dimensionalMode
310  double *RePtr = inParamState.template GetFieldBuffer<double>("refRe");
311  double *betaPtr = inParamState.template GetFieldBuffer<double>("beta");
312  double *powerPtr = inParamState.template GetFieldBuffer<double>("power");
313  // assume Power law, dimensional
314  double mu = (*betaPtr)*pow(refTemperature,(*powerPtr));
315  double Re = 1;
316 
317  if(nonDimensionalMode == 1){
318  mu = 1.0;
319  Re = *RePtr;
320  } if(nonDimensionalMode == 2){
321  mu = 1.0;
322  Re = *RePtr;
323  }
324 
325  // flow conditions
326  // working in dimensional units
327  double rho = refRho;
328  std::vector<double> velocity(numDim,0);
329  double pLo = refPressure;
330  double pHi = pLo + deltaP;
331 
332  double tempLo = refTemperature;
333 
334  if(nonDimensionalMode == 1){
335  rho /= refRho;
336  pLo /= refPressure;
337  pHi /= refPressure;
338  tempLo /= refTemperature;
339  } else if (nonDimensionalMode == 2) {
340  rho /= refRho;
341  pLo /= gamma*refPressure;
342  pHi /= gamma*refPressure;
343  tempLo /= (gamma-1)*refTemperature;
344  }
345 
346  double rhoE = pLo/(gamma-1)/rho;
347 
348  double dPdX = (pHi - pLo)/length;
349  //*messageStream << "dPdX " << dPdX << std::endl;
350 
351  *messageStream << "Poiseulle: Initial state" << std::endl;
352  *messageStream << "\t nonDimensional: " << nonDimensionalMode << std::endl;
353  //*messageStream << "\t Reynolds Number: " << Re << std::endl;
354  *messageStream << "\t rho: " << rho << std::endl;
355  *messageStream << "\t Inlet pressure: " << pLo << std::endl;
356  *messageStream << "\t Outlet pressure: " << pHi << std::endl;
357  *messageStream << "\t temperature: " << tempLo << std::endl;
358  *messageStream << "\t rhoE: " << rhoE << std::endl;
359  *messageStream << "\t dPdX: " << dPdX << std::endl;
360  //*messageStream << "\t u1: " << velocity[0] << std::endl;
361  //*messageStream << "\t u2: " << velocity[1] << std::endl;
362 
363  // initialize the interior points
364  // apply the linear pressure gradient in the flow direction
365  double pi = 3.14159265359;
366  size_t iStart = partitionBufferInterval[0].first;
367  size_t iEnd = partitionBufferInterval[0].second;
368  size_t jStart = partitionBufferInterval[1].first;
369  size_t jEnd = partitionBufferInterval[1].second;
370  size_t kStart = 0;
371  size_t kEnd = 0;
372  size_t nPlane = 0;
373  if(numDim > 2 ){
374  kStart = partitionBufferInterval[2].first;
375  kEnd = partitionBufferInterval[2].second;
376  nPlane = bufferSizes[0]*bufferSizes[1];
377  }
378 
379  for(size_t kIndex = kStart;kIndex <= kEnd;kIndex++){
380  size_t kBufferIndex = kIndex*nPlane;
381  size_t kPartIndex = 0;
382  double z = 0;
383  if (numDim > 2){
384  kPartIndex = (kIndex - kStart) + partitionInterval[2].first;
385  z = kPartIndex*dX[2];
386  }
387 
388  for(size_t jIndex = jStart;jIndex <= jEnd;jIndex++){
389  size_t jkBufferIndex = kBufferIndex + jIndex*bufferSizes[0];
390  size_t jPartIndex = (jIndex - jStart) + partitionInterval[1].first;
391  double y = jPartIndex*dX[1];
392  for(size_t iIndex = iStart;iIndex <= iEnd;iIndex++){
393  size_t bufferIndex = jkBufferIndex + iIndex;
394  size_t iPartIndex = (iIndex - iStart) + partitionInterval[0].first;
395  double x = iPartIndex*dX[0];
396 
397  double pressure = pLo;
398  if (direction == 1) {
399  pressure += dPdX*(xMax-x);
400  if(x == xMin || x == xMax)
401  velocity[0] = Re*dPdX*y*(height-y)/(2*mu);
402  else
403  velocity[0]=0.;
404  } else if (direction == -1) {
405  pressure += dPdX*(x-xMin);
406  if(x == xMin || x == xMax)
407  velocity[0] = Re*dPdX*y*(y-height)/(2*mu);
408  else
409  velocity[0]=0.;
410  } else if (direction == 2) {
411  pressure += dPdX*(yMax-y);
412  if(y == yMin || y == yMax)
413  velocity[1] = Re*dPdX*x*(height-x)/(2*mu);
414  else
415  velocity[1]=0.;
416  } else if (direction == -2) {
417  pressure += dPdX*(y-yMin);
418  if(y == yMin || y == yMax)
419  velocity[1] = Re*dPdX*x*(x-height)/(2*mu);
420  else
421  velocity[1]=0.;
422  } else if (direction == 3) {
423  pressure += dPdX*(zMax-z);
424  if(z == zMin || z == zMax) {
425 
426  velocity[2] = Re*dPdX*x*(height-x)/(2*mu);
427 
428  // height = x
429  // width = y
430  // length = z
431  double sumTerm = 0;
432  int nMax=10;
433  for(int n=1;n<nMax;n++){
434  double beta = (2*n-1)*pi/height;
435  sumTerm += sin(beta*x)/pow((2*n-1),3)*(sinh(beta*y)+sinh(beta*(width-y)))/sinh(beta*width);
436  }
437  sumTerm *= 4*dPdX*height*height/mu/pow(pi,3);
438  velocity[2] -= sumTerm;
439  } else {
440  velocity[2]=0;
441  }
442 
443  } else if (direction == -3) {
444  pressure += dPdX*(z-zMin);
445  if(z == zMin || z == zMax) {
446 
447  velocity[2] = Re*dPdX*x*(x-height)/(2*mu);
448 
449  // height = x
450  // width = y
451  // length = z
452  double sumTerm = 0;
453  int nMax=10;
454  for(int n=1;n<nMax;n++){
455  double beta = (2*n-1)*pi/height;
456  sumTerm += sin(beta*x)/pow((2*n-1),3)*(sinh(beta*y)+sinh(beta*(width-y)))/sinh(beta*width);
457  }
458  sumTerm *= 4*dPdX*height*height/mu/pow(pi,3);
459  velocity[2] += sumTerm;
460  } else {
461  velocity[2]=0;
462  }
463  }
464 
465  rhoPtr[bufferIndex] = rho;
466  rhoEPtr[bufferIndex] = pressure/(gamma-1);
467  for (int iDim=0;iDim<numDim;iDim++){
468  rhoVPtr[bufferIndex+numPointsBuffer*iDim] = rhoPtr[bufferIndex]*velocity[iDim];
469  rhoEPtr[bufferIndex] += 0.5*rho*velocity[iDim]*velocity[iDim];
470  }
471  }
472  }
473  }
474 
475  return(0);
476  };
477 
478  }
479 }
480 #endif
int ComputeTauBuffer(const pcpp::IndexIntervalType &regionInterval, const std::vector< size_t > &bufferSize, int gridType, const std::vector< double > &gridMetrics, const std::vector< double > &gridJacobian, const double &Re, const std::vector< double *> &tvBuffers, const std::vector< double *> &velGradBuffers, std::vector< double *> &tauBuffers)
Definition: ViscidUtil.C:113
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t * bufferSize
void const size_t const size_t const size_t const int const int const double const double const double * rhoVBuffer
Definition: EulerKernels.H:10
int ComputeHeatFluxBuffer(const pcpp::IndexIntervalType &regionInterval, const std::vector< size_t > &bufferSize, int gridType, const std::vector< double > &gridMetrics, const std::vector< double > &gridJacobian, const double &Re, const std::vector< double *> &tvBuffers, const std::vector< double *> &temperatureGradBuffers, std::vector< double *> &heatFluxBuffers)
Definition: ViscidUtil.C:627
void const size_t const size_t * gridSizes
Definition: EulerKernels.H:10
void const size_t const size_t const size_t const double const double double * y
simulation::grid::subregion GridRegionType
Definition: ViscidUtil.H:12
void const size_t const size_t const size_t const int const int * gridType
Definition: EulerKernels.H:10
void const size_t const size_t const size_t const int const double const int const double * velocity
Definition: MetricKernels.H:19
void const size_t const size_t const size_t const double const double * x
int ComputeTVBuffer(const int *numDimPtr, const size_t *bufferSize, const size_t *numPointsPtr, const size_t *bufferInterval, const double *rhoBuffer, const double *rhoVBuffer, const double *rhoEBuffer, double *pressureBuffer, double *tempBuffer, double *rhom1Buffer, double *velBuffer)
Definition: ViscidUtil.C:97
void const size_t const size_t const size_t const int const int const double const double const double const double * rhoEBuffer
Definition: EulerKernels.H:10
Definition: Viscid.f90:1
void const size_t const size_t const size_t const int const int const double const double const double const double const double const double * pressureBuffer
Definition: EulerKernels.H:10
int ComputeTVBufferPower(const pcpp::IndexIntervalType &regionInterval, const std::vector< size_t > &bufferSize, const double *temperatureBuffer, std::vector< double *> &tvBuffer, const double beta, const double power, const double bulkViscFac, const double specificHeat, const double prandtlNumber)
Compute transport coefficients using the power law.
Definition: ViscidUtil.C:14
void const size_t const size_t const size_t const int const double * gridJacobian
Definition: MetricKernels.H:9
void DumpContents(std::ostream &Ostr, const ContainerType &c, std::string del="\)
Dump container contents.
Definition: AppTools.H:117
void const size_t const size_t * bufferSizes
Definition: MetricKernels.H:19
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t * bufferInterval
int InitializePoiseuille(const GridType &inGrid, StateType &inState, StateType &inParamState, const std::vector< double > &inParams, int threadId, std::ostream *messageStream=NULL)
Definition: ViscidUtil.H:82
void const size_t const size_t const size_t const int const int const double const double * rhoBuffer
Definition: EulerKernels.H:10
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
void InitSimple(const ContainerType &inSize)
Definition: IndexUtil.H:169
void const size_t * numPointsBuffer
Definition: MetricKernels.H:19