Nektar++
Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
Nektar::DiffusionLDGNS Class Reference

#include <DiffusionLDGNS.h>

Inheritance diagram for Nektar::DiffusionLDGNS:
[legend]

Static Public Member Functions

static DiffusionSharedPtr create (std::string diffType)
 

Static Public Attributes

static std::string type
 

Protected Member Functions

 DiffusionLDGNS ()
 
virtual void v_InitObject (LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
 
virtual void v_Diffuse (const std::size_t nConvective, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, 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)
 Calculate weak DG Diffusion in the LDG form for the Navier-Stokes (NS) equations: More...
 
void NumericalFluxO1 (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &numericalFluxO1, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
 Builds the numerical flux for the 1st order derivatives. More...
 
void ApplyBCsO1 (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd, Array< OneD, Array< OneD, NekDouble > > &flux01)
 Imposes appropriate bcs for the 1st order derivatives. More...
 
void NumericalFluxO2 (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &qfield, Array< OneD, Array< OneD, NekDouble > > &qflux, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
 Build the numerical flux for the 2nd order derivatives. More...
 
void ApplyBCsO2 (const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const std::size_t var, const std::size_t dir, const Array< OneD, const NekDouble > &qfield, const Array< OneD, const NekDouble > &qFwd, const Array< OneD, const NekDouble > &qBwd, Array< OneD, NekDouble > &penaltyflux)
 Imposes appropriate bcs for the 2nd order derivatives. More...
 
virtual void v_SetHomoDerivs (Array< OneD, Array< OneD, NekDouble > > &deriv)
 
virtual Array< OneD, Array< OneD, Array< OneD, NekDouble > > > & v_GetFluxTensor ()
 

Protected Attributes

NekDouble m_C11
 Penalty coefficient for LDGNS. More...
 
Array< OneD, NekDoublem_traceOneOverH
 h scaling for penalty term More...
 
Array< OneD, Array< OneD, NekDouble > > m_traceVel
 
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
 
LibUtilities::SessionReaderSharedPtr m_session
 
NekDouble m_Twall
 
EquationOfStateSharedPtr m_eos
 Equation of system for computing temperature. More...
 
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_viscTensor
 
Array< OneD, Array< OneD, NekDouble > > m_homoDerivs
 
std::size_t m_spaceDim
 
std::size_t m_diffDim
 
- Protected Attributes inherited from Nektar::SolverUtils::Diffusion
DiffusionFluxVecCB m_fluxVector
 
DiffusionFluxVecCBNS m_fluxVectorNS
 
DiffusionFluxPenaltyNS m_fluxPenaltyNS
 

Additional Inherited Members

- Public Member Functions inherited from Nektar::SolverUtils::Diffusion
virtual SOLVER_UTILS_EXPORT ~Diffusion ()
 
SOLVER_UTILS_EXPORT void InitObject (LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
 
SOLVER_UTILS_EXPORT void Diffuse (const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayofArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayofArray)
 
SOLVER_UTILS_EXPORT void FluxVec (Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &fluxvector)
 
template<typename FuncPointerT , typename ObjectPointerT >
void SetFluxVector (FuncPointerT func, ObjectPointerT obj)
 
void SetFluxVector (DiffusionFluxVecCB fluxVector)
 
template<typename FuncPointerT , typename ObjectPointerT >
void SetFluxVectorNS (FuncPointerT func, ObjectPointerT obj)
 
void SetFluxVectorNS (DiffusionFluxVecCBNS fluxVector)
 
template<typename FuncPointerT , typename ObjectPointerT >
void SetFluxPenaltyNS (FuncPointerT func, ObjectPointerT obj)
 
void SetFluxPenaltyNS (DiffusionFluxPenaltyNS flux)
 
void SetHomoDerivs (Array< OneD, Array< OneD, NekDouble > > &deriv)
 
virtual Array< OneD, Array< OneD, Array< OneD, NekDouble > > > & GetFluxTensor ()
 

Detailed Description

Definition at line 50 of file DiffusionLDGNS.h.

Constructor & Destructor Documentation

◆ DiffusionLDGNS()

Nektar::DiffusionLDGNS::DiffusionLDGNS ( )
protected

Definition at line 49 of file DiffusionLDGNS.cpp.

50 {
51 }

Member Function Documentation

◆ ApplyBCsO1()

void Nektar::DiffusionLDGNS::ApplyBCsO1 ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
const Array< OneD, Array< OneD, NekDouble > > &  inarray,
const Array< OneD, Array< OneD, NekDouble > > &  pFwd,
const Array< OneD, Array< OneD, NekDouble > > &  pBwd,
Array< OneD, Array< OneD, NekDouble > > &  flux01 
)
protected

Imposes appropriate bcs for the 1st order derivatives.

Definition at line 357 of file DiffusionLDGNS.cpp.

References Nektar::SpatialDomains::eDirichlet, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::ePeriodic, m_eos, m_traceNormals, m_Twall, Vmath::Smul(), Vmath::Vadd(), Vmath::Vcopy(), Vmath::Vdiv(), Vmath::Vmul(), Vmath::Vvtvp(), and Vmath::Zero().

Referenced by NumericalFluxO1().

363 {
364  boost::ignore_unused(pBwd);
365 
366  std::size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
367  std::size_t nScalars = inarray.num_elements();
368 
369  Array<OneD, NekDouble> tmp1{nTracePts, 0.0};
370  Array<OneD, NekDouble> tmp2{nTracePts, 0.0};
371  Array<OneD, NekDouble> Tw{nTracePts, m_Twall};
372 
373  Array< OneD, Array<OneD, NekDouble > > scalarVariables{nScalars};
374 
375  // Extract internal values of the scalar variables for Neumann bcs
376  for (std::size_t i = 0; i < nScalars; ++i)
377  {
378  scalarVariables[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
379  }
380 
381  // Compute boundary conditions for velocities
382  for (std::size_t i = 0; i < nScalars-1; ++i)
383  {
384  // Note that cnt has to loop on nBndRegions and nBndEdges
385  // and has to be reset to zero per each equation
386  std::size_t cnt = 0;
387  std::size_t nBndRegions = fields[i+1]->
388  GetBndCondExpansions().num_elements();
389  for (std::size_t j = 0; j < nBndRegions; ++j)
390  {
391  if (fields[i+1]->GetBndConditions()[j]->
392  GetBoundaryConditionType() == SpatialDomains::ePeriodic)
393  {
394  continue;
395  }
396 
397  std::size_t nBndEdges = fields[i+1]->
398  GetBndCondExpansions()[j]->GetExpSize();
399  for (std::size_t e = 0; e < nBndEdges; ++e)
400  {
401  std::size_t nBndEdgePts = fields[i+1]->
402  GetBndCondExpansions()[j]->GetExp(e)->GetTotPoints();
403 
404  std::size_t id1 = fields[i+1]->
405  GetBndCondExpansions()[j]->GetPhys_Offset(e);
406 
407  std::size_t id2 = fields[0]->GetTrace()->
408  GetPhys_Offset(fields[0]->GetTraceMap()->
409  GetBndCondTraceToGlobalTraceMap(cnt++));
410 
411  if (boost::iequals(fields[i]->GetBndConditions()[j]->
412  GetUserDefined(),"WallViscous") ||
413  boost::iequals(fields[i]->GetBndConditions()[j]->
414  GetUserDefined(),"WallAdiabatic"))
415  {
416  // Reinforcing bcs for velocity in case of Wall bcs
417  Vmath::Zero(nBndEdgePts, &scalarVariables[i][id2], 1);
418 
419  }
420  else if (
421  boost::iequals(fields[i]->GetBndConditions()[j]->
422  GetUserDefined(),"Wall") ||
423  boost::iequals(fields[i]->GetBndConditions()[j]->
424  GetUserDefined(),"Symmetry"))
425  {
426  // Symmetry bc: normal velocity is zero
427  // get all velocities at once because we need u.n
428  if (i==0)
429  {
430  // tmp1 = -(u.n)
431  Vmath::Zero(nBndEdgePts, tmp1, 1);
432  for (std::size_t k = 0; k < nScalars-1; ++k)
433  {
434  Vmath::Vdiv(nBndEdgePts,
435  &(fields[k+1]->GetBndCondExpansions()[j]->
436  UpdatePhys())[id1], 1,
437  &(fields[0]->GetBndCondExpansions()[j]->
438  UpdatePhys())[id1], 1,
439  &scalarVariables[k][id2], 1);
440  Vmath::Vvtvp(nBndEdgePts,
441  &m_traceNormals[k][id2], 1,
442  &scalarVariables[k][id2], 1,
443  &tmp1[0], 1,
444  &tmp1[0], 1);
445  }
446  Vmath::Smul(nBndEdgePts, -1.0,
447  &tmp1[0], 1,
448  &tmp1[0], 1);
449 
450  // u_i - (u.n)n_i
451  for (std::size_t k = 0; k < nScalars-1; ++k)
452  {
453  Vmath::Vvtvp(nBndEdgePts,
454  &tmp1[0], 1,
455  &m_traceNormals[k][id2], 1,
456  &scalarVariables[k][id2], 1,
457  &scalarVariables[k][id2], 1);
458  }
459  }
460  }
461  else if (fields[i]->GetBndConditions()[j]->
462  GetBoundaryConditionType() ==
464  {
465  // Imposing velocity bcs if not Wall
466  Vmath::Vdiv(nBndEdgePts,
467  &(fields[i+1]->GetBndCondExpansions()[j]->
468  UpdatePhys())[id1], 1,
469  &(fields[0]->GetBndCondExpansions()[j]->
470  UpdatePhys())[id1], 1,
471  &scalarVariables[i][id2], 1);
472  }
473 
474  // For Dirichlet boundary condition: uflux = u_bcs
475  if (fields[i]->GetBndConditions()[j]->
476  GetBoundaryConditionType() ==
478  {
479  Vmath::Vcopy(nBndEdgePts,
480  &scalarVariables[i][id2], 1,
481  &fluxO1[i][id2], 1);
482  }
483 
484  // For Neumann boundary condition: uflux = u_+
485  else if ((fields[i]->GetBndConditions()[j])->
486  GetBoundaryConditionType() ==
488  {
489  Vmath::Vcopy(nBndEdgePts,
490  &pFwd[i][id2], 1,
491  &fluxO1[i][id2], 1);
492  }
493 
494  // Building kinetic energy to be used for T bcs
495  Vmath::Vmul(nBndEdgePts,
496  &scalarVariables[i][id2], 1,
497  &scalarVariables[i][id2], 1,
498  &tmp1[id2], 1);
499 
500  Vmath::Smul(nBndEdgePts, 0.5,
501  &tmp1[id2], 1,
502  &tmp1[id2], 1);
503 
504  Vmath::Vadd(nBndEdgePts,
505  &tmp2[id2], 1,
506  &tmp1[id2], 1,
507  &tmp2[id2], 1);
508  }
509  }
510  }
511 
512  // Compute boundary conditions for temperature
513  std::size_t cnt = 0;
514  std::size_t nBndRegions = fields[nScalars]->
515  GetBndCondExpansions().num_elements();
516  for (std::size_t j = 0; j < nBndRegions; ++j)
517  {
518  if (fields[nScalars]->GetBndConditions()[j]->
519  GetBoundaryConditionType() ==
521  {
522  continue;
523  }
524 
525  std::size_t nBndEdges = fields[nScalars]->
526  GetBndCondExpansions()[j]->GetExpSize();
527  for (std::size_t e = 0; e < nBndEdges; ++e)
528  {
529  std::size_t nBndEdgePts = fields[nScalars]->
530  GetBndCondExpansions()[j]->GetExp(e)->GetTotPoints();
531 
532  std::size_t id1 = fields[nScalars]->
533  GetBndCondExpansions()[j]->GetPhys_Offset(e);
534 
535  std::size_t id2 = fields[0]->GetTrace()->
536  GetPhys_Offset(fields[0]->GetTraceMap()->
537  GetBndCondTraceToGlobalTraceMap(cnt++));
538 
539  // Imposing Temperature Twall at the wall
540  if (boost::iequals(fields[nScalars]->GetBndConditions()[j]->
541  GetUserDefined(),"WallViscous"))
542  {
543  Vmath::Vcopy(nBndEdgePts,
544  &Tw[0], 1,
545  &scalarVariables[nScalars-1][id2], 1);
546  }
547  // Imposing Temperature through condition on the Energy
548  // for no wall boundaries (e.g. farfield)
549  else if (fields[nScalars]->GetBndConditions()[j]->
550  GetBoundaryConditionType() ==
552  {
553  // Use equation of state to evaluate temperature
554  NekDouble rho, ene;
555  for(std::size_t n = 0; n < nBndEdgePts; ++n)
556  {
557  rho = fields[0]->
558  GetBndCondExpansions()[j]->
559  GetPhys()[id1+n];
560  ene = fields[nScalars]->
561  GetBndCondExpansions()[j]->
562  GetPhys()[id1 +n] / rho - tmp2[id2+n];
563  scalarVariables[nScalars-1][id2+n] =
564  m_eos->GetTemperature(rho, ene);
565  }
566  }
567 
568  // For Dirichlet boundary condition: uflux = u_bcs
569  if (fields[nScalars]->GetBndConditions()[j]->
570  GetBoundaryConditionType() == SpatialDomains::eDirichlet &&
571  !boost::iequals(fields[nScalars]->GetBndConditions()[j]
572  ->GetUserDefined(), "WallAdiabatic"))
573  {
574  Vmath::Vcopy(nBndEdgePts,
575  &scalarVariables[nScalars-1][id2], 1,
576  &fluxO1[nScalars-1][id2], 1);
577 
578  }
579 
580  // For Neumann boundary condition: uflux = u_+
581  else if (((fields[nScalars]->GetBndConditions()[j])->
582  GetBoundaryConditionType() == SpatialDomains::eNeumann) ||
583  boost::iequals(fields[nScalars]->GetBndConditions()[j]->
584  GetUserDefined(), "WallAdiabatic"))
585  {
586  Vmath::Vcopy(nBndEdgePts,
587  &pFwd[nScalars-1][id2], 1,
588  &fluxO1[nScalars-1][id2], 1);
589 
590  }
591  }
592  }
593 }
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:445
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
Definition: Vmath.cpp:244
EquationOfStateSharedPtr m_eos
Equation of system for computing temperature.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:216
double NekDouble
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:302
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:186

◆ ApplyBCsO2()

void Nektar::DiffusionLDGNS::ApplyBCsO2 ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
const std::size_t  var,
const std::size_t  dir,
const Array< OneD, const NekDouble > &  qfield,
const Array< OneD, const NekDouble > &  qFwd,
const Array< OneD, const NekDouble > &  qBwd,
Array< OneD, NekDouble > &  penaltyflux 
)
protected

Imposes appropriate bcs for the 2nd order derivatives.

Definition at line 664 of file DiffusionLDGNS.cpp.

References ASSERTL0, Nektar::SpatialDomains::eDirichlet, Nektar::SpatialDomains::eNeumann, Nektar::SpatialDomains::ePeriodic, m_spaceDim, m_traceNormals, Vmath::Vmul(), and Vmath::Zero().

Referenced by NumericalFluxO2().

672 {
673  boost::ignore_unused(qfield, qBwd);
674 
675  std::size_t cnt = 0;
676  std::size_t nBndRegions = fields[var]->GetBndCondExpansions().num_elements();
677  // Loop on the boundary regions to apply appropriate bcs
678  for (std::size_t i = 0; i < nBndRegions; ++i)
679  {
680  // Number of boundary regions related to region 'i'
681  std::size_t nBndEdges = fields[var]->
682  GetBndCondExpansions()[i]->GetExpSize();
683 
684  if (fields[var]->GetBndConditions()[i]->GetBoundaryConditionType()
686  {
687  continue;
688  }
689 
690  // Weakly impose bcs by modifying flux values
691  for (std::size_t e = 0; e < nBndEdges; ++e)
692  {
693  std::size_t nBndEdgePts = fields[var]->
694  GetBndCondExpansions()[i]->GetExp(e)->GetTotPoints();
695 
696  std::size_t id2 = fields[0]->GetTrace()->
697  GetPhys_Offset(fields[0]->GetTraceMap()->
698  GetBndCondTraceToGlobalTraceMap(cnt++));
699 
700  // In case of Dirichlet bcs:
701  // uflux = gD
702  if (fields[var]->GetBndConditions()[i]->
703  GetBoundaryConditionType() == SpatialDomains::eDirichlet
704  && !boost::iequals(fields[var]->GetBndConditions()[i]->
705  GetUserDefined(), "WallAdiabatic"))
706  {
707  Vmath::Vmul(nBndEdgePts,
708  &m_traceNormals[dir][id2], 1,
709  &qFwd[id2], 1,
710  &penaltyflux[id2], 1);
711  }
712  // 3.4) In case of Neumann bcs:
713  // uflux = u+
714  else if ((fields[var]->GetBndConditions()[i])->
715  GetBoundaryConditionType() == SpatialDomains::eNeumann)
716  {
717  ASSERTL0(false,
718  "Neumann bcs not implemented for LDGNS");
719 
720  /*
721  Vmath::Vmul(nBndEdgePts,
722  &m_traceNormals[dir][id2], 1,
723  &(fields[var]->
724  GetBndCondExpansions()[i]->
725  UpdatePhys())[id1], 1,
726  &penaltyflux[id2], 1);
727  */
728  }
729  else if (boost::iequals(fields[var]->GetBndConditions()[i]->
730  GetUserDefined(), "WallAdiabatic"))
731  {
732  if ((var == m_spaceDim + 1))
733  {
734  Vmath::Zero(nBndEdgePts, &penaltyflux[id2], 1);
735  }
736  else
737  {
738 
739  Vmath::Vmul(nBndEdgePts,
740  &m_traceNormals[dir][id2], 1,
741  &qFwd[id2], 1,
742  &penaltyflux[id2], 1);
743 
744  }
745  }
746  }
747  }
748 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:186

◆ create()

static DiffusionSharedPtr Nektar::DiffusionLDGNS::create ( std::string  diffType)
inlinestatic

Definition at line 53 of file DiffusionLDGNS.h.

54  {
55  boost::ignore_unused(diffType);
56  return DiffusionSharedPtr(new DiffusionLDGNS());
57  }
std::shared_ptr< Diffusion > DiffusionSharedPtr
A shared pointer to an EquationSystem object.
Definition: Diffusion.h:183

◆ NumericalFluxO1()

void Nektar::DiffusionLDGNS::NumericalFluxO1 ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
const Array< OneD, Array< OneD, NekDouble > > &  inarray,
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &  numericalFluxO1,
const Array< OneD, Array< OneD, NekDouble > > &  pFwd,
const Array< OneD, Array< OneD, NekDouble > > &  pBwd 
)
protected

Builds the numerical flux for the 1st order derivatives.

Definition at line 318 of file DiffusionLDGNS.cpp.

References ApplyBCsO1(), m_spaceDim, m_traceNormals, and Vmath::Vmul().

Referenced by v_Diffuse().

325 {
326  std::size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
327  std::size_t nScalars = inarray.num_elements();
328 
329  //Upwind
330  Array<OneD, Array<OneD, NekDouble> > numflux{nScalars};
331  for (std::size_t i = 0; i < nScalars; ++i)
332  {
333  numflux[i] = {pFwd[i]};
334  }
335 
336  // Modify the values in case of boundary interfaces
337  if (fields[0]->GetBndCondExpansions().num_elements())
338  {
339  ApplyBCsO1(fields, inarray, pFwd, pBwd, numflux);
340  }
341 
342  // Splitting the numerical flux into the dimensions
343  for (std::size_t j = 0; j < m_spaceDim; ++j)
344  {
345  for (std::size_t i = 0; i < nScalars; ++i)
346  {
347  Vmath::Vmul(nTracePts, m_traceNormals[j], 1,numflux[i], 1,
348  numericalFluxO1[j][i], 1);
349  }
350  }
351 }
void ApplyBCsO1(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd, Array< OneD, Array< OneD, NekDouble > > &flux01)
Imposes appropriate bcs for the 1st order derivatives.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:186

◆ NumericalFluxO2()

void Nektar::DiffusionLDGNS::NumericalFluxO2 ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &  qfield,
Array< OneD, Array< OneD, NekDouble > > &  qflux,
const Array< OneD, Array< OneD, NekDouble > > &  pFwd,
const Array< OneD, Array< OneD, NekDouble > > &  pBwd 
)
protected

Build the numerical flux for the 2nd order derivatives.

Definition at line 599 of file DiffusionLDGNS.cpp.

References ApplyBCsO2(), Nektar::SolverUtils::Diffusion::m_fluxPenaltyNS, m_traceNormals, m_traceOneOverH, Vmath::Vadd(), Vmath::Vcopy(), Vmath::Vmul(), and Vmath::Vvtvp().

Referenced by v_Diffuse().

605 {
606  std::size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
607  std::size_t nVariables = fields.num_elements();
608 
609  // Initialize penalty flux
610  Array<OneD, Array<OneD, NekDouble> > fluxPen{nVariables-1};
611  for (std::size_t i = 0; i < nVariables-1; ++i)
612  {
613  fluxPen[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
614  }
615 
616  // Get penalty flux
617  m_fluxPenaltyNS(uFwd, uBwd, fluxPen);
618 
619  // Evaluate Riemann flux
620  // qflux = \hat{q} \cdot u = q \cdot n
621  // Notice: i = 1 (first row of the viscous tensor is zero)
622 
623  Array<OneD, NekDouble > qFwd{nTracePts};
624  Array<OneD, NekDouble > qBwd{nTracePts};
625  Array<OneD, NekDouble > qtemp{nTracePts};
626  Array<OneD, NekDouble > qfluxtemp{nTracePts, 0.0};
627  std::size_t nDim = fields[0]->GetCoordim(0);
628  for (std::size_t i = 1; i < nVariables; ++i)
629  {
630  qflux[i] = Array<OneD, NekDouble> {nTracePts, 0.0};
631  for (std::size_t j = 0; j < nDim; ++j)
632  {
633  // Compute qFwd and qBwd value of qfield in position 'ji'
634  fields[i]->GetFwdBwdTracePhys(qfield[j][i], qFwd, qBwd);
635 
636  // Downwind
637  Vmath::Vcopy(nTracePts, qBwd, 1, qfluxtemp, 1);
638 
639  // Multiply the Riemann flux by the trace normals
640  Vmath::Vmul(nTracePts, m_traceNormals[j], 1, qfluxtemp, 1,
641  qfluxtemp, 1);
642 
643  // Add penalty term
644  Vmath::Vvtvp(nTracePts, m_traceOneOverH, 1, fluxPen[i-1], 1,
645  qfluxtemp, 1, qfluxtemp, 1);
646 
647  // Impose weak boundary condition with flux
648  if (fields[0]->GetBndCondExpansions().num_elements())
649  {
650  ApplyBCsO2(fields, i, j, qfield[j][i], qFwd, qBwd, qfluxtemp);
651  }
652 
653  // Store the final flux into qflux
654  Vmath::Vadd(nTracePts, qfluxtemp, 1, qflux[i], 1, qflux[i], 1);
655  }
656  }
657 }
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:445
void ApplyBCsO2(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const std::size_t var, const std::size_t dir, const Array< OneD, const NekDouble > &qfield, const Array< OneD, const NekDouble > &qFwd, const Array< OneD, const NekDouble > &qBwd, Array< OneD, NekDouble > &penaltyflux)
Imposes appropriate bcs for the 2nd order derivatives.
DiffusionFluxPenaltyNS m_fluxPenaltyNS
Definition: Diffusion.h:152
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array< OneD, NekDouble > m_traceOneOverH
h scaling for penalty term
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:302
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:186

◆ v_Diffuse()

void Nektar::DiffusionLDGNS::v_Diffuse ( const std::size_t  nConvectiveFields,
const Array< OneD, MultiRegions::ExpListSharedPtr > &  fields,
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 
)
protectedvirtual

Calculate weak DG Diffusion in the LDG form for the Navier-Stokes (NS) equations:

\( \langle\psi, \hat{u}\cdot n\rangle - \langle\nabla\psi \cdot u\rangle \langle\phi, \hat{q}\cdot n\rangle - (\nabla \phi \cdot q) \rangle \)

The equations that need a diffusion operator are those related with the velocities and with the energy.

Implements Nektar::SolverUtils::Diffusion.

Definition at line 211 of file DiffusionLDGNS.cpp.

References m_diffDim, Nektar::SolverUtils::Diffusion::m_fluxVectorNS, m_homoDerivs, m_spaceDim, m_viscTensor, Vmath::Neg(), NumericalFluxO1(), NumericalFluxO2(), and Vmath::Vadd().

218 {
219  std::size_t nDim = fields[0]->GetCoordim(0);
220  std::size_t nPts = fields[0]->GetTotPoints();
221  std::size_t nCoeffs = fields[0]->GetNcoeffs();
222  std::size_t nScalars = inarray.num_elements();
223  std::size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
224 
225  Array<OneD, NekDouble> tmp1{nCoeffs};
226  Array<OneD, Array<OneD, NekDouble> > tmp2{nConvectiveFields};
227 
228  Array<OneD, Array<OneD, Array<OneD, NekDouble> > >
229  numericalFluxO1{m_spaceDim};
230  Array<OneD, Array<OneD, Array<OneD, NekDouble> > >
231  derivativesO1{m_spaceDim};
232 
233  for (std::size_t j = 0; j < m_spaceDim; ++j)
234  {
235  numericalFluxO1[j] = Array<OneD, Array<OneD, NekDouble> >{nScalars};
236  derivativesO1[j] = Array<OneD, Array<OneD, NekDouble> >{nScalars};
237 
238  for (std::size_t i = 0; i < nScalars; ++i)
239  {
240  numericalFluxO1[j][i] = Array<OneD, NekDouble>{nTracePts, 0.0};
241  derivativesO1[j][i] = Array<OneD, NekDouble>{nPts, 0.0};
242  }
243  }
244 
245  // Compute the numerical fluxes for the first order derivatives
246  NumericalFluxO1(fields, inarray, numericalFluxO1, pFwd, pBwd);
247 
248  for (std::size_t j = 0; j < nDim; ++j)
249  {
250  for (std::size_t i = 0; i < nScalars; ++i)
251  {
252  fields[i]->IProductWRTDerivBase (j, inarray[i], tmp1);
253  Vmath::Neg (nCoeffs, tmp1, 1);
254  fields[i]->AddTraceIntegral (numericalFluxO1[j][i],
255  tmp1);
256  fields[i]->SetPhysState (false);
257  fields[i]->MultiplyByElmtInvMass(tmp1, tmp1);
258  fields[i]->BwdTrans (tmp1, derivativesO1[j][i]);
259  }
260  }
261 
262  // For 3D Homogeneous 1D only take derivatives in 3rd direction
263  if (m_diffDim == 1)
264  {
265  for (std::size_t i = 0; i < nScalars; ++i)
266  {
267  derivativesO1[2][i] = m_homoDerivs[i];
268  }
269  }
270 
271  // Initialisation viscous tensor
272  m_viscTensor = Array<OneD, Array<OneD, Array<OneD, NekDouble> > >
273  {m_spaceDim};
274  for (std::size_t j = 0; j < m_spaceDim; ++j)
275  {
276  m_viscTensor[j] = Array<OneD, Array<OneD, NekDouble> >{nScalars+1};
277  for (std::size_t i = 0; i < nScalars+1; ++i)
278  {
279  m_viscTensor[j][i] = Array<OneD, NekDouble>{nPts, 0.0};
280  }
281  }
282 
283  Array<OneD, Array<OneD, NekDouble> > viscousFlux{nConvectiveFields};
284  for (std::size_t i = 0; i < nConvectiveFields; ++i)
285  {
286  viscousFlux[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
287  }
288 
289  m_fluxVectorNS(inarray, derivativesO1, m_viscTensor);
290 
291  // Compute u from q_{\eta} and q_{\xi}
292  // Obtain numerical fluxes
293  NumericalFluxO2(fields, m_viscTensor, viscousFlux, pFwd, pBwd);
294 
295  for (std::size_t i = 0; i < nConvectiveFields; ++i)
296  {
297  tmp2[i] = Array<OneD, NekDouble>{nCoeffs, 0.0};
298 
299  for (std::size_t j = 0; j < nDim; ++j)
300  {
301  fields[i]->IProductWRTDerivBase(j, m_viscTensor[j][i], tmp1);
302  Vmath::Vadd(nCoeffs, tmp1, 1, tmp2[i], 1, tmp2[i], 1);
303  }
304 
305  // Evaulate <\phi, \hat{F}\cdot n> - outarray[i]
306  Vmath::Neg (nCoeffs, tmp2[i], 1);
307  fields[i]->AddTraceIntegral (viscousFlux[i], tmp2[i]);
308  fields[i]->SetPhysState (false);
309  fields[i]->MultiplyByElmtInvMass(tmp2[i], tmp2[i]);
310  fields[i]->BwdTrans (tmp2[i], outarray[i]);
311  }
312 }
void NumericalFluxO1(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &numericalFluxO1, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
Builds the numerical flux for the 1st order derivatives.
DiffusionFluxVecCBNS m_fluxVectorNS
Definition: Diffusion.h:151
void NumericalFluxO2(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &qfield, Array< OneD, Array< OneD, NekDouble > > &qflux, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
Build the numerical flux for the 2nd order derivatives.
Array< OneD, Array< OneD, NekDouble > > m_homoDerivs
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:399
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_viscTensor
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:302

◆ v_GetFluxTensor()

virtual Array<OneD, Array<OneD, Array<OneD, NekDouble> > >& Nektar::DiffusionLDGNS::v_GetFluxTensor ( )
inlineprotectedvirtual

Reimplemented from Nektar::SolverUtils::Diffusion.

Definition at line 133 of file DiffusionLDGNS.h.

134  {
135  return m_viscTensor;
136  }
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_viscTensor

◆ v_InitObject()

void Nektar::DiffusionLDGNS::v_InitObject ( LibUtilities::SessionReaderSharedPtr  pSession,
Array< OneD, MultiRegions::ExpListSharedPtr pFields 
)
protectedvirtual

Reimplemented from Nektar::SolverUtils::Diffusion.

Definition at line 53 of file DiffusionLDGNS.cpp.

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::SpatialDomains::ePeriodic, Vmath::Fill(), Nektar::GetEquationOfStateFactory(), Nektar::LocalRegions::Expansion1D::GetGeom1D(), m_C11, m_diffDim, m_eos, m_session, m_spaceDim, m_traceNormals, m_traceOneOverH, m_traceVel, m_Twall, Vmath::Sdiv(), Vmath::Svtsvtp(), and Vmath::Vcopy().

56 {
57  m_session = pSession;
58  m_session->LoadParameter ("Twall", m_Twall, 300.15);
59 
60  // Setting up the normals
61  std::size_t nDim = pFields[0]->GetCoordim(0);
62  std::size_t nTracePts = pFields[0]->GetTrace()->GetTotPoints();
63 
64  m_spaceDim = nDim;
65  if (pSession->DefinesSolverInfo("HOMOGENEOUS"))
66  {
67  m_spaceDim = 3;
68  }
69 
70  m_diffDim = m_spaceDim - nDim;
71 
72  m_traceVel = Array<OneD, Array<OneD, NekDouble> >{m_spaceDim};
73  m_traceNormals = Array<OneD, Array<OneD, NekDouble> >{m_spaceDim};
74  for(std::size_t i = 0; i < m_spaceDim; ++i)
75  {
76  m_traceVel[i] = Array<OneD, NekDouble> {nTracePts, 0.0};
77  m_traceNormals[i] = Array<OneD, NekDouble> {nTracePts};
78  }
79  pFields[0]->GetTrace()->GetNormals(m_traceNormals);
80 
81  // Create equation of state object
82  std::string eosType;
83  m_session->LoadSolverInfo("EquationOfState",
84  eosType, "IdealGas");
86  .CreateInstance(eosType, m_session);
87 
88 
89  // Set up {h} reference on the trace for penalty term
90  //
91  // Note, this shold be replaced with something smarter when merging
92  // LDG with IP
93 
94  // Get min h per element
95  std::size_t nElements = pFields[0]->GetExpSize();
96  Array<OneD, NekDouble> hEle{nElements, 1.0};
97  for (std::size_t e = 0; e < nElements; e++)
98  {
99  NekDouble h{1.0e+10};
100  std::size_t expDim = pFields[0]->GetShapeDimension();
101  switch(expDim)
102  {
103  case 3:
104  {
106  exp3D = pFields[0]->GetExp(e)->as<LocalRegions::Expansion3D>();
107  for(std::size_t i = 0; i < exp3D->GetNedges(); ++i)
108  {
109  h = std::min(h, exp3D->GetGeom3D()->GetEdge(i)->GetVertex(0)->
110  dist(*(exp3D->GetGeom3D()->GetEdge(i)->GetVertex(1))));
111  }
112  break;
113  }
114 
115  case 2:
116  {
118  exp2D = pFields[0]->GetExp(e)->as<LocalRegions::Expansion2D>();
119  for(std::size_t i = 0; i < exp2D->GetNedges(); ++i)
120  {
121  h = std::min(h, exp2D->GetGeom2D()->GetEdge(i)->GetVertex(0)->
122  dist(*(exp2D->GetGeom2D()->GetEdge(i)->GetVertex(1))));
123  }
124  break;
125  }
126  case 1:
127  {
129  exp1D = pFields[0]->GetExp(e)->as<LocalRegions::Expansion1D>();
130 
131  h = std::min(h, exp1D->GetGeom1D()->GetVertex(0)->
132  dist(*(exp1D->GetGeom1D()->GetVertex(1))));
133 
134  break;
135  }
136  default:
137  {
138  ASSERTL0(false,"Dimension out of bound.")
139  }
140  }
141 
142  // Store scaling
143  hEle[e] = h;
144  }
145  // Expand h from elements to points
146  std::size_t nPts = pFields[0]->GetTotPoints();
147  Array<OneD, NekDouble> hElePts{nPts, 0.0};
148  Array<OneD, NekDouble> tmp;
149  for (std::size_t e = 0; e < pFields[0]->GetExpSize(); e++)
150  {
151  std::size_t nElmtPoints = pFields[0]->GetExp(e)->GetTotPoints();
152  std::size_t physOffset = pFields[0]->GetPhys_Offset(e);
153  Vmath::Fill(nElmtPoints, hEle[e],
154  tmp = hElePts + physOffset, 1);
155  }
156  // Get Fwd and Bwd traces
157  Array<OneD, NekDouble> Fwd{nTracePts, 0.0};
158  Array<OneD, NekDouble> Bwd{nTracePts, 0.0};
159  pFields[0]->GetFwdBwdTracePhys(hElePts, Fwd, Bwd);
160  // Fix boundaries
161  std::size_t cnt = 0;
162  std::size_t nBndRegions = pFields[0]->GetBndCondExpansions().num_elements();
163  // Loop on the boundary regions
164  for (std::size_t i = 0; i < nBndRegions; ++i)
165  {
166  // Number of boundary regions related to region 'i'
167  std::size_t nBndEdges = pFields[0]->
168  GetBndCondExpansions()[i]->GetExpSize();
169 
170  if (pFields[0]->GetBndConditions()[i]->GetBoundaryConditionType()
172  {
173  continue;
174  }
175 
176  // Get value from interior
177  for (std::size_t e = 0; e < nBndEdges; ++e)
178  {
179  std::size_t nBndEdgePts = pFields[0]->
180  GetBndCondExpansions()[i]->GetExp(e)->GetTotPoints();
181 
182  std::size_t id2 = pFields[0]->GetTrace()->
183  GetPhys_Offset(pFields[0]->GetTraceMap()->
184  GetBndCondTraceToGlobalTraceMap(cnt++));
185 
186  Vmath::Vcopy(nBndEdgePts, &Fwd[id2], 1, &Bwd[id2], 1);
187  }
188  }
189  // Get average of traces
190  Array<OneD, NekDouble> traceH{nTracePts, 1.0};
191  m_traceOneOverH = Array<OneD, NekDouble> {nTracePts, 1.0};
192  Vmath::Svtsvtp(nTracePts, 0.5, Fwd, 1, 0.5, Bwd, 1, traceH, 1);
193  // Multiply by coefficient = - C11 / h
194  m_session->LoadParameter ("LDGNSc11", m_C11, 1.0);
195  Vmath::Sdiv(nTracePts, -m_C11, traceH, 1, m_traceOneOverH, 1);
196 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
Array< OneD, Array< OneD, NekDouble > > m_traceVel
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/y.
Definition: Vmath.cpp:274
EquationOfStateSharedPtr m_eos
Equation of system for computing temperature.
std::shared_ptr< Expansion3D > Expansion3DSharedPtr
Definition: Expansion2D.h:49
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
EquationOfStateFactory & GetEquationOfStateFactory()
Declaration of the equation of state factory singleton.
NekDouble m_C11
Penalty coefficient for LDGNS.
double NekDouble
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array< OneD, NekDouble > m_traceOneOverH
h scaling for penalty term
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
Definition: Expansion1D.h:47
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
vvtvvtp (scalar times vector plus scalar times vector):
Definition: Vmath.cpp:594
LibUtilities::SessionReaderSharedPtr m_session
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
Definition: Expansion1D.h:51

◆ v_SetHomoDerivs()

virtual void Nektar::DiffusionLDGNS::v_SetHomoDerivs ( Array< OneD, Array< OneD, NekDouble > > &  deriv)
inlineprotectedvirtual

Reimplemented from Nektar::SolverUtils::Diffusion.

Definition at line 127 of file DiffusionLDGNS.h.

129  {
130  m_homoDerivs = deriv;
131  }
Array< OneD, Array< OneD, NekDouble > > m_homoDerivs

Member Data Documentation

◆ m_C11

NekDouble Nektar::DiffusionLDGNS::m_C11
protected

Penalty coefficient for LDGNS.

Definition at line 65 of file DiffusionLDGNS.h.

Referenced by v_InitObject().

◆ m_diffDim

std::size_t Nektar::DiffusionLDGNS::m_diffDim
protected

Definition at line 82 of file DiffusionLDGNS.h.

Referenced by v_Diffuse(), and v_InitObject().

◆ m_eos

EquationOfStateSharedPtr Nektar::DiffusionLDGNS::m_eos
protected

Equation of system for computing temperature.

Definition at line 75 of file DiffusionLDGNS.h.

Referenced by ApplyBCsO1(), and v_InitObject().

◆ m_homoDerivs

Array<OneD, Array<OneD, NekDouble> > Nektar::DiffusionLDGNS::m_homoDerivs
protected

Definition at line 79 of file DiffusionLDGNS.h.

Referenced by v_Diffuse().

◆ m_session

LibUtilities::SessionReaderSharedPtr Nektar::DiffusionLDGNS::m_session
protected

Definition at line 72 of file DiffusionLDGNS.h.

Referenced by v_InitObject().

◆ m_spaceDim

std::size_t Nektar::DiffusionLDGNS::m_spaceDim
protected

Definition at line 81 of file DiffusionLDGNS.h.

Referenced by ApplyBCsO2(), NumericalFluxO1(), v_Diffuse(), and v_InitObject().

◆ m_traceNormals

Array<OneD, Array<OneD, NekDouble> > Nektar::DiffusionLDGNS::m_traceNormals
protected

◆ m_traceOneOverH

Array<OneD, NekDouble> Nektar::DiffusionLDGNS::m_traceOneOverH
protected

h scaling for penalty term

Definition at line 68 of file DiffusionLDGNS.h.

Referenced by NumericalFluxO2(), and v_InitObject().

◆ m_traceVel

Array<OneD, Array<OneD, NekDouble> > Nektar::DiffusionLDGNS::m_traceVel
protected

Definition at line 70 of file DiffusionLDGNS.h.

Referenced by v_InitObject().

◆ m_Twall

NekDouble Nektar::DiffusionLDGNS::m_Twall
protected

Definition at line 73 of file DiffusionLDGNS.h.

Referenced by ApplyBCsO1(), and v_InitObject().

◆ m_viscTensor

Array<OneD, Array<OneD, Array<OneD, NekDouble> > > Nektar::DiffusionLDGNS::m_viscTensor
protected

Definition at line 77 of file DiffusionLDGNS.h.

Referenced by v_Diffuse().

◆ type

std::string Nektar::DiffusionLDGNS::type
static
Initial value:

Definition at line 59 of file DiffusionLDGNS.h.