35#ifndef NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
36#define NEKTAR_SOLVERS_COMPRESSIBLEFLOWSOLVER_EQUATIONSYSTEMS_NAVIERSTOKESCFE_H
108 const size_t nSpaceDim,
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 (
size_t 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 (
size_t f = 0; f < nConvectiveFields; ++f)
457 for (
size_t d = 0;
d < nDim; ++
d)
459 for (
size_t 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 (
size_t f = 0; f < nConvectiveFields; ++f)
477 inTmp[f] = inarray[f][
p];
485 for (
size_t d = 0;
d < nDim; ++
d)
487 outArrTmp[f + nConvectiveFields *
d] = 0.0;
494 for (
size_t d = 0;
d < nDim; ++
d)
496 normalTmp[
d] = normal[
d][
p];
503 for (
size_t nderiv = 0; nderiv < nDim; ++nderiv)
506 for (
size_t f = 0; f < nConvectiveFields; ++f)
508 qfieldsTmp[f] = qfields[nderiv][f][
p];
511 for (
size_t 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 (
size_t f = 0; f < nConvectiveFields; ++f)
539 outarray[0][f][
p] = outArrTmp[f];
544 for (
size_t d = 0;
d < nDim; ++
d)
546 for (
size_t 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.
EquationOfStateSharedPtr m_eos
Equation of system for computing temperature.
NavierStokesCFE(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
void CalcViscosity(const Array< OneD, const Array< OneD, NekDouble > > &inaverg, Array< OneD, NekDouble > &mu)
void SpecialBndTreat(Array< OneD, Array< OneD, NekDouble > > &consvar)
For very special treatment. For general boundaries it does nothing But for WallViscous and WallAdiaba...
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)
void v_InitObject(bool DeclareField=true) override
Initialization object for CompressibleFlowSystem class.
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.
static std::string className
void InitObject_Explicit()
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
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
void GetViscousFluxVectorConservVar(const size_t 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 v_ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables) override
bool m_is_shockCaptPhys
flag for shock capturing switch on/off an enum could be added for more options
MultiRegions::ContFieldSharedPtr m_C0ProjectExp
bool v_SupportsShockCaptType(const std::string type) const override
void GetViscousSymmtrFluxConservVar(const size_t 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.
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)
~NavierStokesCFE() override=default
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.
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 GetPhysicalAV(const Array< OneD, const Array< OneD, NekDouble > > &physfield)
void GetViscousFluxVectorConservVar(const size_t 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)
bool m_is_diffIP
flag to switch between IP and LDG an enum could be added for more options
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)
void GetArtificialViscosity(const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &muav)
void GetViscosityAndThermalCondFromTempKernel(const T &temperature, T &mu, T &thermalCond)
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.
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
std::vector< double > d(NPUPPER *NPUPPER)
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