35 #ifndef NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
36 #define NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
124 virtual void v_InitObject(
bool DeclareField =
true)
override;
170 std::vector<std::string> &variables)
override;
172 template <
class T,
typename =
typename std::enable_if<
173 std::is_floating_point<T>::value ||
176 T &mu, T &thermalCond)
180 thermalCond = tRa * mu;
183 template <
class T,
typename =
typename std::enable_if<
184 std::is_floating_point<T>::value ||
191 mu =
m_varConv->GetDynamicViscosity(temperature);
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,
214 const T *inaverg,
const T *injumpp,
const T &mu, T *outarray)
217 unsigned short nDim_plus_one = nDim + 1;
218 unsigned short FluxDirection_plus_one = FluxDirection + 1;
219 unsigned short DerivDirection_plus_one = DerivDirection + 1;
222 NekDouble one_minus_gammaoPr = 1.0 - gammaoPr;
225 constexpr
NekDouble TwoThird = 2. * OneThird;
226 constexpr
NekDouble FourThird = 4. * OneThird;
228 if (DerivDirection == FluxDirection)
234 T oneOrho = 1.0 / inaverg[0];
236 std::array<T, 3> u = {{0.0, 0.0, 0.0}};
237 std::array<T, 3> u2 = {{0.0, 0.0, 0.0}};
239 for (
unsigned short d = 0; d < nDim; ++d)
241 u[d] = inaverg[d + 1] * oneOrho;
247 T E_minus_u2sum = inaverg[nDim_plus_one];
248 E_minus_u2sum *= oneOrho;
249 E_minus_u2sum -= u2sum;
256 T tmp1 = OneThird * u2[FluxDirection] + u2sum;
257 tmp1 += gammaoPr * E_minus_u2sum;
260 T tmp2 = gammaoPr * injumpp[nDim_plus_one] - tmp1;
264 for (
unsigned short d = 0; d < nDim; ++d)
266 unsigned short d_plus_one = d + 1;
268 T outTmpD = injumpp[d_plus_one] - u[d] * injumpp[0];
271 T tmp3 = one_minus_gammaoPr * u[d];
272 outTmpE += tmp3 * injumpp[d_plus_one];
274 if (d == FluxDirection)
276 outTmpD *= FourThird;
277 T tmp4 = OneThird * u[FluxDirection];
278 outTmpE += tmp4 * injumpp[FluxDirection_plus_one];
281 outarray[d_plus_one] = outTmpD;
286 outarray[nDim_plus_one] = outTmpE;
294 T oneOrho = 1.0 / inaverg[0];
296 std::array<T, 3> u, u2;
298 for (
unsigned short d = 0; d < nDim; ++d)
300 unsigned short d_plus_one = d + 1;
301 u[d] = inaverg[d_plus_one] * oneOrho;
306 outarray[d_plus_one] = 0.0;
310 T E_minus_u2sum = inaverg[nDim_plus_one];
311 E_minus_u2sum *= oneOrho;
312 E_minus_u2sum -= u2sum;
319 T tmp1 = u[DerivDirection] * injumpp[0] -
320 injumpp[DerivDirection_plus_one];
322 outarray[FluxDirection_plus_one] = nu * tmp1;
325 injumpp[FluxDirection_plus_one] - u[FluxDirection] * injumpp[0];
326 outarray[DerivDirection_plus_one] = nu * tmp1;
328 tmp1 = OneThird * u[FluxDirection] * u[DerivDirection];
332 TwoThird * u[FluxDirection] * injumpp[DerivDirection_plus_one];
336 tmp1 = u[DerivDirection] * injumpp[FluxDirection_plus_one] - tmp1;
337 outarray[nDim_plus_one] = nu * tmp1;
345 template <
bool IS_TRACE>
352 size_t nConvectiveFields = inarray.size();
353 size_t nPts = inarray[0].size();
354 size_t n_nonZero = nConvectiveFields - 1;
357 constexpr
unsigned short nOutMax = 3 - 2 * IS_TRACE;
358 constexpr
unsigned short nVarMax = 5;
359 constexpr
unsigned short nDimMax = 3;
367 m_varConv->GetTemperature(inarray, temperature);
369 thermalConductivity);
374 size_t sizeVec = (nPts / vec_t::width) * vec_t::width;
377 for (;
p < sizeVec;
p += vec_t::width)
380 alignas(vec_t::alignment) std::array<vec_t, nVarMax> inTmp,
382 alignas(vec_t::alignment) std::array<vec_t, nDimMax> normalTmp;
383 alignas(vec_t::alignment) std::array<vec_t, nVarMax * nOutMax>
387 for (
size_t f = 0; f < nConvectiveFields; ++f)
397 for (
int d = 0; d < nDim; ++d)
399 outArrTmp[f + nConvectiveFields * d] = 0.0;
405 for (
size_t d = 0; d < nDim; ++d)
415 for (
size_t nderiv = 0; nderiv < nDim; ++nderiv)
418 for (
size_t f = 0; f < nConvectiveFields; ++f)
420 qfieldsTmp[f].load(&(qfields[nderiv][f][
p]),
424 for (
size_t d = 0; d < nDim; ++d)
427 nDim, d, nderiv, inTmp.data(), qfieldsTmp.data(), muV,
432 for (
size_t f = 0; f < nConvectiveFields; ++f)
434 outArrTmp[f] += normalTmp[d] * outTmp[f];
439 for (
size_t f = 0; f < nConvectiveFields; ++f)
441 outArrTmp[f + nConvectiveFields * d] += outTmp[f];
450 for (
int f = 0; f < nConvectiveFields; ++f)
457 for (
int d = 0; d < nDim; ++d)
459 for (
int f = 0; f < nConvectiveFields; ++f)
461 outArrTmp[f + nConvectiveFields * d].store(
469 for (;
p < nPts; ++
p)
471 std::array<NekDouble, nVarMax> inTmp, qfieldsTmp, outTmp;
472 std::array<NekDouble, nDimMax> normalTmp;
473 std::array<NekDouble, nVarMax * nOutMax> outArrTmp{{}};
475 for (
int f = 0; f < nConvectiveFields; ++f)
477 inTmp[f] = inarray[f][
p];
485 for (
int d = 0; d < nDim; ++d)
487 outArrTmp[f + nConvectiveFields * d] = 0.0;
494 for (
int d = 0; d < nDim; ++d)
496 normalTmp[d] = normal[d][
p];
503 for (
int nderiv = 0; nderiv < nDim; ++nderiv)
506 for (
int f = 0; f < nConvectiveFields; ++f)
508 qfieldsTmp[f] = qfields[nderiv][f][
p];
511 for (
int d = 0; d < nDim; ++d)
514 nDim, d, nderiv, inTmp.data(), qfieldsTmp.data(), muS,
519 for (
size_t f = 0; f < nConvectiveFields; ++f)
521 outArrTmp[f] += normalTmp[d] * outTmp[f];
526 for (
size_t f = 0; f < nConvectiveFields; ++f)
528 outArrTmp[f + nConvectiveFields * d] += outTmp[f];
537 for (
int f = 0; f < nConvectiveFields; ++f)
539 outarray[0][f][
p] = outArrTmp[f];
544 for (
int d = 0; d < nDim; ++d)
546 for (
int f = 0; f < nConvectiveFields; ++f)
549 outArrTmp[f + nConvectiveFields * d];
557 for (
int i = 1; i < n_nonZero + 1; ++i)
559 nonZeroIndex[n_nonZero - i] = nConvectiveFields - i;
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)
virtual ~NavierStokesCFE()
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)
void InitObject_Explicit()
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::string m_ViscosityType
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ContField > ContFieldSharedPtr
std::shared_ptr< EquationSystem > EquationSystemSharedPtr
A shared pointer to an EquationSystem object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
The above copyright notice and this permission notice shall be included.
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
static constexpr struct tinysimd::is_not_aligned_t is_not_aligned
typename abi< ScalarType, width >::type simd