Nektar++
NavierStokesCFE.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File NavierStokesCFE.h
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: NavierStokes equations in conservative variable
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
36 #define NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
37 
41 #include <MultiRegions/ContField.h>
42 
43 namespace Nektar
44 {
45 /**
46  *
47  *
48  **/
50 {
51 public:
52  friend class MemoryManager<NavierStokesCFE>;
53 
54  // Creates an instance of this class
58  {
61  p->InitObject();
62  return p;
63  }
64  // Name of class
65  static std::string className;
66 
67  virtual ~NavierStokesCFE();
68 
69 protected:
70  std::string m_ViscosityType;
71  /// flag to switch between constant viscosity and Sutherland
72  /// an enum could be added for more options
73  bool m_is_mu_variable{false};
74  /// flag to switch between IP and LDG
75  /// an enum could be added for more options
76  bool m_is_diffIP{false};
77  /// flag for shock capturing switch on/off
78  /// an enum could be added for more options
79  bool m_is_shockCaptPhys{false};
80 
84 
85  std::string m_physicalSensorType;
86  std::string m_smoothing;
88 
89  /// Equation of system for computing temperature
91 
95 
98 
100  const int nDim, const Array<OneD, Array<OneD, NekDouble>> &inarray,
101  const TensorOfArray3D<NekDouble> &qfields,
102  TensorOfArray3D<NekDouble> &outarray,
103  Array<OneD, int> &nonZeroIndex = NullInt1DArray,
104  const Array<OneD, Array<OneD, NekDouble>> &normal =
106 
108  const int nSpaceDim, const Array<OneD, Array<OneD, NekDouble>> &inaverg,
109  const Array<OneD, Array<OneD, NekDouble>> &inarray,
110  TensorOfArray3D<NekDouble> &outarray, Array<OneD, int> &nonZeroIndex,
111  const Array<OneD, Array<OneD, NekDouble>> &normals);
112 
114 
116  const Array<OneD, Array<OneD, NekDouble>> &inarray,
117  Array<OneD, NekDouble> &muav);
118 
119  void CalcViscosity(const Array<OneD, const Array<OneD, NekDouble>> &inaverg,
121 
122  void InitObject_Explicit();
123 
124  virtual void v_InitObject(bool DeclareField = true) override;
125 
126  virtual void v_DoDiffusion(
127  const Array<OneD, Array<OneD, NekDouble>> &inarray,
128  Array<OneD, Array<OneD, NekDouble>> &outarray,
129  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
130  const Array<OneD, Array<OneD, NekDouble>> &pBwd) override;
131 
132  virtual void v_GetViscousFluxVector(
133  const Array<OneD, const Array<OneD, NekDouble>> &physfield,
134  TensorOfArray3D<NekDouble> &derivatives,
135  TensorOfArray3D<NekDouble> &viscousTensor);
136 
137  virtual void v_GetViscousFluxVectorDeAlias(
138  const Array<OneD, const Array<OneD, NekDouble>> &physfield,
139  TensorOfArray3D<NekDouble> &derivatives,
140  TensorOfArray3D<NekDouble> &viscousTensor);
141 
143  const Array<OneD, const Array<OneD, NekDouble>> &physfield);
144 
147 
148  virtual void v_GetFluxPenalty(
149  const Array<OneD, const Array<OneD, NekDouble>> &uFwd,
150  const Array<OneD, const Array<OneD, NekDouble>> &uBwd,
151  Array<OneD, Array<OneD, NekDouble>> &penaltyCoeff);
152 
154  const Array<OneD, NekDouble> &temperature, Array<OneD, NekDouble> &mu,
155  Array<OneD, NekDouble> &thermalCond);
156 
157  void GetDivCurlSquared(
159  const Array<OneD, Array<OneD, NekDouble>> &cnsVar,
161  const Array<OneD, Array<OneD, NekDouble>> &cnsVarFwd,
162  const Array<OneD, Array<OneD, NekDouble>> &cnsVarBwd);
163 
166  Array<OneD, NekDouble> &curlSquare);
167 
168  virtual void v_ExtraFldOutput(
169  std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
170  std::vector<std::string> &variables) override;
171 
172  template <class T, typename = typename std::enable_if<
173  std::is_floating_point<T>::value ||
175  inline void GetViscosityAndThermalCondFromTempKernel(const T &temperature,
176  T &mu, T &thermalCond)
177  {
178  GetViscosityFromTempKernel(temperature, mu);
179  NekDouble tRa = m_Cp / m_Prandtl;
180  thermalCond = tRa * mu;
181  }
182 
183  template <class T, typename = typename std::enable_if<
184  std::is_floating_point<T>::value ||
186  inline void GetViscosityFromTempKernel(const T &temperature, T &mu)
187  {
188  // Variable viscosity through the Sutherland's law
189  if (m_is_mu_variable)
190  {
191  mu = m_varConv->GetDynamicViscosity(temperature);
192  }
193  else
194  {
195  mu = m_muRef;
196  }
197  }
198 
199  /**
200  * @brief Calculate diffusion flux using the Jacobian form.
201  *
202  * @param in
203  *
204  * @param out
205  * outarray[nvars] flux
206  */
207  template <class T, typename = typename std::enable_if<
208  std::is_floating_point<T>::value ||
211  const unsigned short nDim, const unsigned short FluxDirection,
212  const unsigned short DerivDirection,
213  // these need to be a pointers because of the custom allocator of vec_t
214  const T *inaverg, const T *injumpp, const T &mu, T *outarray)
215  {
216  // Constants
217  unsigned short nDim_plus_one = nDim + 1;
218  unsigned short FluxDirection_plus_one = FluxDirection + 1;
219  unsigned short DerivDirection_plus_one = DerivDirection + 1;
220 
221  NekDouble gammaoPr = m_gamma / m_Prandtl;
222  NekDouble one_minus_gammaoPr = 1.0 - gammaoPr;
223 
224  constexpr NekDouble OneThird = 1. / 3.;
225  constexpr NekDouble TwoThird = 2. * OneThird;
226  constexpr NekDouble FourThird = 4. * OneThird;
227 
228  if (DerivDirection == FluxDirection)
229  {
230  // rho flux always zero
231  outarray[0] = 0.0; // store 1x
232 
233  // load 1/rho
234  T oneOrho = 1.0 / inaverg[0]; // load 1x
235  // get vel, vel^2, sum of vel^2
236  std::array<T, 3> u = {{0.0, 0.0, 0.0}};
237  std::array<T, 3> u2 = {{0.0, 0.0, 0.0}};
238  T u2sum{};
239  for (unsigned short d = 0; d < nDim; ++d)
240  {
241  u[d] = inaverg[d + 1] * oneOrho; // load 1x
242  u2[d] = u[d] * u[d];
243  u2sum += u2[d];
244  }
245 
246  // get E - sum v^2
247  T E_minus_u2sum = inaverg[nDim_plus_one]; // load 1x
248  E_minus_u2sum *= oneOrho;
249  E_minus_u2sum -= u2sum;
250 
251  // get nu = mu/rho
252  T nu = mu * oneOrho; // load 1x
253 
254  // ^^^^ above is almost the same for both loops
255 
256  T tmp1 = OneThird * u2[FluxDirection] + u2sum;
257  tmp1 += gammaoPr * E_minus_u2sum;
258  tmp1 *= injumpp[0]; // load 1x
259 
260  T tmp2 = gammaoPr * injumpp[nDim_plus_one] - tmp1; // load 1x
261 
262  // local var for energy output
263  T outTmpE = 0.0;
264  for (unsigned short d = 0; d < nDim; ++d)
265  {
266  unsigned short d_plus_one = d + 1;
267  // flux[rhou, rhov, rhow]
268  T outTmpD = injumpp[d_plus_one] - u[d] * injumpp[0];
269  outTmpD *= nu;
270  // flux rhoE
271  T tmp3 = one_minus_gammaoPr * u[d];
272  outTmpE += tmp3 * injumpp[d_plus_one];
273 
274  if (d == FluxDirection)
275  {
276  outTmpD *= FourThird;
277  T tmp4 = OneThird * u[FluxDirection];
278  outTmpE += tmp4 * injumpp[FluxDirection_plus_one];
279  }
280 
281  outarray[d_plus_one] = outTmpD; // store 1x
282  }
283 
284  outTmpE += tmp2;
285  outTmpE *= nu;
286  outarray[nDim_plus_one] = outTmpE; // store 1x
287  }
288  else
289  {
290  // rho flux always zero
291  outarray[0] = 0.0; // store 1x
292 
293  // load 1/rho
294  T oneOrho = 1.0 / inaverg[0]; // load 1x
295  // get vel, vel^2, sum of vel^2
296  std::array<T, 3> u, u2;
297  T u2sum{};
298  for (unsigned short d = 0; d < nDim; ++d)
299  {
300  unsigned short d_plus_one = d + 1;
301  u[d] = inaverg[d_plus_one] * oneOrho; // load 1x
302  u2[d] = u[d] * u[d];
303  u2sum += u2[d];
304  // Not all directions are set
305  // one could work out the one that is not set
306  outarray[d_plus_one] = 0.0; // store 1x
307  }
308 
309  // get E - sum v^2
310  T E_minus_u2sum = inaverg[nDim_plus_one]; // load 1x
311  E_minus_u2sum *= oneOrho;
312  E_minus_u2sum -= u2sum;
313 
314  // get nu = mu/rho
315  T nu = mu * oneOrho; // load 1x
316 
317  // ^^^^ above is almost the same for both loops
318 
319  T tmp1 = u[DerivDirection] * injumpp[0] -
320  injumpp[DerivDirection_plus_one]; // load 2x
321  tmp1 *= TwoThird;
322  outarray[FluxDirection_plus_one] = nu * tmp1; // store 1x
323 
324  tmp1 =
325  injumpp[FluxDirection_plus_one] - u[FluxDirection] * injumpp[0];
326  outarray[DerivDirection_plus_one] = nu * tmp1; // store 1x
327 
328  tmp1 = OneThird * u[FluxDirection] * u[DerivDirection];
329  tmp1 *= injumpp[0];
330 
331  T tmp2 =
332  TwoThird * u[FluxDirection] * injumpp[DerivDirection_plus_one];
333 
334  tmp1 += tmp2;
335 
336  tmp1 = u[DerivDirection] * injumpp[FluxDirection_plus_one] - tmp1;
337  outarray[nDim_plus_one] = nu * tmp1; // store 1x
338  }
339  }
340 
341  /**
342  * @brief Return the flux vector for the IP diffusion problem, based on
343  * conservative variables
344  */
345  template <bool IS_TRACE>
347  const int nDim, const Array<OneD, Array<OneD, NekDouble>> &inarray,
348  const TensorOfArray3D<NekDouble> &qfields,
349  TensorOfArray3D<NekDouble> &outarray, Array<OneD, int> &nonZeroIndex,
350  const Array<OneD, Array<OneD, NekDouble>> &normal)
351  {
352  size_t nConvectiveFields = inarray.size();
353  size_t nPts = inarray[0].size();
354  size_t n_nonZero = nConvectiveFields - 1;
355 
356  // max outfield dimensions
357  constexpr unsigned short nOutMax = 3 - 2 * IS_TRACE;
358  constexpr unsigned short nVarMax = 5;
359  constexpr unsigned short nDimMax = 3;
360 
361  // Update viscosity and thermal conductivity
362  // unfortunately the artificial viscosity is difficult to vectorize
363  // with the current implementation
364  Array<OneD, NekDouble> temperature(nPts, 0.0);
365  Array<OneD, NekDouble> mu(nPts, 0.0);
366  Array<OneD, NekDouble> thermalConductivity(nPts, 0.0);
367  m_varConv->GetTemperature(inarray, temperature);
368  GetViscosityAndThermalCondFromTemp(temperature, mu,
369  thermalConductivity);
370 
371  // vector loop
372  using namespace tinysimd;
373  using vec_t = simd<NekDouble>;
374  size_t sizeVec = (nPts / vec_t::width) * vec_t::width;
375  size_t p = 0;
376 
377  for (; p < sizeVec; p += vec_t::width)
378  {
379  // there is a significant penalty to use std::vector
380  alignas(vec_t::alignment) std::array<vec_t, nVarMax> inTmp,
381  qfieldsTmp, outTmp;
382  alignas(vec_t::alignment) std::array<vec_t, nDimMax> normalTmp;
383  alignas(vec_t::alignment) std::array<vec_t, nVarMax * nOutMax>
384  outArrTmp{{}};
385 
386  // rearrenge and load data
387  for (size_t f = 0; f < nConvectiveFields; ++f)
388  {
389  inTmp[f].load(&(inarray[f][p]), is_not_aligned);
390  // zero output vector
391  if (IS_TRACE)
392  {
393  outArrTmp[f] = 0.0;
394  }
395  else
396  {
397  for (int d = 0; d < nDim; ++d)
398  {
399  outArrTmp[f + nConvectiveFields * d] = 0.0;
400  }
401  }
402  }
403  if (IS_TRACE)
404  {
405  for (size_t d = 0; d < nDim; ++d)
406  {
407  normalTmp[d].load(&(normal[d][p]), is_not_aligned);
408  }
409  }
410 
411  // get viscosity
412  vec_t muV{};
413  muV.load(&(mu[p]), is_not_aligned);
414 
415  for (size_t nderiv = 0; nderiv < nDim; ++nderiv)
416  {
417  // rearrenge and load data
418  for (size_t f = 0; f < nConvectiveFields; ++f)
419  {
420  qfieldsTmp[f].load(&(qfields[nderiv][f][p]),
422  }
423 
424  for (size_t d = 0; d < nDim; ++d)
425  {
427  nDim, d, nderiv, inTmp.data(), qfieldsTmp.data(), muV,
428  outTmp.data());
429 
430  if (IS_TRACE)
431  {
432  for (size_t f = 0; f < nConvectiveFields; ++f)
433  {
434  outArrTmp[f] += normalTmp[d] * outTmp[f];
435  }
436  }
437  else
438  {
439  for (size_t f = 0; f < nConvectiveFields; ++f)
440  {
441  outArrTmp[f + nConvectiveFields * d] += outTmp[f];
442  }
443  }
444  }
445  }
446 
447  // store data
448  if (IS_TRACE)
449  {
450  for (int f = 0; f < nConvectiveFields; ++f)
451  {
452  outArrTmp[f].store(&(outarray[0][f][p]), is_not_aligned);
453  }
454  }
455  else
456  {
457  for (int d = 0; d < nDim; ++d)
458  {
459  for (int f = 0; f < nConvectiveFields; ++f)
460  {
461  outArrTmp[f + nConvectiveFields * d].store(
462  &(outarray[d][f][p]), is_not_aligned);
463  }
464  }
465  }
466  }
467 
468  // scalar loop
469  for (; p < nPts; ++p)
470  {
471  std::array<NekDouble, nVarMax> inTmp, qfieldsTmp, outTmp;
472  std::array<NekDouble, nDimMax> normalTmp;
473  std::array<NekDouble, nVarMax * nOutMax> outArrTmp{{}};
474  // rearrenge and load data
475  for (int f = 0; f < nConvectiveFields; ++f)
476  {
477  inTmp[f] = inarray[f][p];
478  // zero output vector
479  if (IS_TRACE)
480  {
481  outArrTmp[f] = 0.0;
482  }
483  else
484  {
485  for (int d = 0; d < nDim; ++d)
486  {
487  outArrTmp[f + nConvectiveFields * d] = 0.0;
488  }
489  }
490  }
491 
492  if (IS_TRACE)
493  {
494  for (int d = 0; d < nDim; ++d)
495  {
496  normalTmp[d] = normal[d][p];
497  }
498  }
499 
500  // get viscosity
501  NekDouble muS = mu[p];
502 
503  for (int nderiv = 0; nderiv < nDim; ++nderiv)
504  {
505  // rearrenge and load data
506  for (int f = 0; f < nConvectiveFields; ++f)
507  {
508  qfieldsTmp[f] = qfields[nderiv][f][p];
509  }
510 
511  for (int d = 0; d < nDim; ++d)
512  {
514  nDim, d, nderiv, inTmp.data(), qfieldsTmp.data(), muS,
515  outTmp.data());
516 
517  if (IS_TRACE)
518  {
519  for (size_t f = 0; f < nConvectiveFields; ++f)
520  {
521  outArrTmp[f] += normalTmp[d] * outTmp[f];
522  }
523  }
524  else
525  {
526  for (size_t f = 0; f < nConvectiveFields; ++f)
527  {
528  outArrTmp[f + nConvectiveFields * d] += outTmp[f];
529  }
530  }
531  }
532  }
533 
534  // store data
535  if (IS_TRACE)
536  {
537  for (int f = 0; f < nConvectiveFields; ++f)
538  {
539  outarray[0][f][p] = outArrTmp[f];
540  }
541  }
542  else
543  {
544  for (int d = 0; d < nDim; ++d)
545  {
546  for (int f = 0; f < nConvectiveFields; ++f)
547  {
548  outarray[d][f][p] =
549  outArrTmp[f + nConvectiveFields * d];
550  }
551  }
552  }
553  }
554 
555  // this is always the same, it should be initialized with the IP class
556  nonZeroIndex = Array<OneD, int>{n_nonZero, 0};
557  for (int i = 1; i < n_nonZero + 1; ++i)
558  {
559  nonZeroIndex[n_nonZero - i] = nConvectiveFields - i;
560  }
561  }
562 };
563 
564 } // namespace Nektar
565 #endif
VariableConverterSharedPtr m_varConv
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void CalcViscosity(const Array< OneD, const Array< OneD, NekDouble >> &inaverg, Array< OneD, NekDouble > &mu)
EquationOfStateSharedPtr m_eos
Equation of system for computing temperature.
NavierStokesCFE(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
virtual void v_GetViscousFluxVector(const Array< OneD, const Array< OneD, NekDouble >> &physfield, TensorOfArray3D< NekDouble > &derivatives, TensorOfArray3D< NekDouble > &viscousTensor)
Return the flux vector for the LDG diffusion problem.
void GetDivCurlFromDvelT(const TensorOfArray3D< NekDouble > &pVarDer, Array< OneD, NekDouble > &div, Array< OneD, NekDouble > &curlSquare)
Get divergence and curl from velocity derivative tensor.
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
virtual void v_InitObject(bool DeclareField=true) override
Initialization object for CompressibleFlowSystem class.
void SpecialBndTreat(Array< OneD, Array< OneD, NekDouble >> &consvar)
For very special treatment. For general boundaries it does nothing But for WallViscous and WallAdiaba...
void GetViscousFluxVectorConservVar(const int nDim, const Array< OneD, Array< OneD, NekDouble >> &inarray, const TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &outarray, Array< OneD, int > &nonZeroIndex, const Array< OneD, Array< OneD, NekDouble >> &normal)
Return the flux vector for the IP diffusion problem, based on conservative variables.
void GetPhysicalAV(const Array< OneD, const Array< OneD, NekDouble >> &physfield)
void GetDivCurlSquared(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &cnsVar, Array< OneD, NekDouble > &div, Array< OneD, NekDouble > &curlSquare, const Array< OneD, Array< OneD, NekDouble >> &cnsVarFwd, const Array< OneD, Array< OneD, NekDouble >> &cnsVarBwd)
Get divergence and curl squared.
virtual void v_DoDiffusion(const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd) override
Apply artificial diffusion (Laplacian operator)
void GetArtificialViscosity(const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &muav)
static std::string className
void GetViscousFluxVectorConservVar(const int nDim, const Array< OneD, Array< OneD, NekDouble >> &inarray, const TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &outarray, Array< OneD, int > &nonZeroIndex=NullInt1DArray, const Array< OneD, Array< OneD, NekDouble >> &normal=NullNekDoubleArrayOfArray)
std::string m_physicalSensorType
NekDouble m_thermalConductivityRef
bool m_is_mu_variable
flag to switch between constant viscosity and Sutherland an enum could be added for more options
bool m_is_shockCaptPhys
flag for shock capturing switch on/off an enum could be added for more options
virtual void v_GetViscousFluxVectorDeAlias(const Array< OneD, const Array< OneD, NekDouble >> &physfield, TensorOfArray3D< NekDouble > &derivatives, TensorOfArray3D< NekDouble > &viscousTensor)
Return the flux vector for the LDG diffusion problem.
MultiRegions::ContFieldSharedPtr m_C0ProjectExp
void GetViscosityAndThermalCondFromTemp(const Array< OneD, NekDouble > &temperature, Array< OneD, NekDouble > &mu, Array< OneD, NekDouble > &thermalCond)
Update viscosity todo: add artificial viscosity here.
void C0Smooth(Array< OneD, NekDouble > &field)
bool m_is_diffIP
flag to switch between IP and LDG an enum could be added for more options
void GetViscousSymmtrFluxConservVar(const int nSpaceDim, const Array< OneD, Array< OneD, NekDouble >> &inaverg, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &outarray, Array< OneD, int > &nonZeroIndex, const Array< OneD, Array< OneD, NekDouble >> &normals)
Calculate and return the Symmetric flux in IP method.
virtual void v_ExtraFldOutput(std::vector< Array< OneD, NekDouble >> &fieldcoeffs, std::vector< std::string > &variables) override
void Ducros(Array< OneD, NekDouble > &field)
void GetViscousFluxBilinearFormKernel(const unsigned short nDim, const unsigned short FluxDirection, const unsigned short DerivDirection, const T *inaverg, const T *injumpp, const T &mu, T *outarray)
Calculate diffusion flux using the Jacobian form.
void GetViscosityFromTempKernel(const T &temperature, T &mu)
virtual void v_GetFluxPenalty(const Array< OneD, const Array< OneD, NekDouble >> &uFwd, const Array< OneD, const Array< OneD, NekDouble >> &uBwd, Array< OneD, Array< OneD, NekDouble >> &penaltyCoeff)
Return the penalty vector for the LDGNS diffusion problem.
void GetViscosityAndThermalCondFromTempKernel(const T &temperature, T &mu, T &thermalCond)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:277
std::shared_ptr< EquationSystem > EquationSystemSharedPtr
A shared pointer to an EquationSystem object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
static Array< OneD, int > NullInt1DArray
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
std::shared_ptr< EquationOfState > EquationOfStateSharedPtr
A shared pointer to an equation of state object.
tinysimd::simd< NekDouble > vec_t
double NekDouble
static constexpr struct tinysimd::is_not_aligned_t is_not_aligned
typename abi< ScalarType, width >::type simd
Definition: tinysimd.hpp:80