VertexCFD  0.0-dev
VertexCFD_InitialCondition_IncompressibleTurbulentChannel_impl.hpp
1 #ifndef VERTEXCFD_INITIALCONDITION_INCOMPRESSIBLETURBULENTCHANNEL_IMPL_HPP
2 #define VERTEXCFD_INITIALCONDITION_INCOMPRESSIBLETURBULENTCHANNEL_IMPL_HPP
3 
4 #include "utils/VertexCFD_Utils_SmoothMath.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
6 
7 #include <Panzer_GlobalIndexer.hpp>
8 #include <Panzer_HierarchicParallelism.hpp>
9 #include <Panzer_PureBasis.hpp>
10 #include <Panzer_Workset_Utilities.hpp>
11 
12 #include "utils/VertexCFD_Utils_Constants.hpp"
13 
14 #include <Teuchos_Array.hpp>
15 
16 #include <cmath>
17 #include <random>
18 #include <string>
19 
20 namespace VertexCFD
21 {
22 namespace InitialCondition
23 {
24 //---------------------------------------------------------------------------//
25 template<class EvalType, class Traits, int NumSpaceDim>
26 IncompressibleTurbulentChannel<EvalType, Traits, NumSpaceDim>::
27  IncompressibleTurbulentChannel(const Teuchos::ParameterList& ic_params,
28  const panzer::PureBasis& basis)
29  : _lagrange_pressure("lagrange_pressure", basis.functional)
30  , _temperature("temperature", basis.functional)
31  , _basis_name(basis.name())
32  , _nu(ic_params.get<double>("Kinematic Viscosity"))
33  , _h(ic_params.get<double>("Half Width"))
34  , _Re_tau(ic_params.get<double>("Friction Reynolds Number"))
35  , _u_tau(_Re_tau * _nu / _h)
36  , _L_x(ic_params.get<double>("L_x"))
37  , _L_z(ic_params.get<double>("L_z"))
38  , _add_rands(true)
39  , _rands(Kokkos::ViewAllocateWithoutInitializing("Turb rands"),
40  basis.numCells(),
41  basis.cardinality())
42  , _nb_modes(3)
43  , _U_0(0.0)
44  , _solve_temp(ic_params.isType<double>("Temperature"))
45  , _T_init(std::numeric_limits<double>::quiet_NaN())
46 {
47  // Get number of modes if present (default is 3 modes)
48  if (ic_params.isType<int>("Number of Modes"))
49  {
50  _nb_modes = ic_params.get<int>("Number of Modes");
51  }
52 
53  // Check to see if random perturbations should be added (default true)
54  if (ic_params.isType<bool>("Add Random Perturbations"))
55  {
56  _add_rands = ic_params.get<bool>("Add Random Perturbations");
57  }
58 
59  // Calculate bulk velocity from Re_b/Re_tau correlations
60  const double Re_b = std::pow(_Re_tau / 0.09, 1.0 / 0.88);
61  const double U_b = Re_b * _nu / 2.0 / _h;
62  _U_0 = 1.28 * std::pow(Re_b, -0.0116) * U_b;
63 
64  // Populate random number array
65  if (_add_rands)
66  {
67  auto rands_host
68  = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _rands);
69 
70  std::default_random_engine generator;
71  std::uniform_real_distribution<double> interval(-1.0, 1.0);
72 
73  for (int i = 0; i < basis.numCells(); ++i)
74  {
75  for (int j = 0; j < basis.cardinality(); ++j)
76  {
77  rands_host(i, j) = interval(generator);
78  }
79  }
80 
81  Kokkos::deep_copy(_rands, rands_host);
82  }
83 
84  // Add evaluated fields
85  this->addEvaluatedField(_lagrange_pressure);
86  this->addUnsharedField(_lagrange_pressure.fieldTag().clone());
87 
88  Utils::addEvaluatedVectorField(
89  *this, basis.functional, _velocity, "velocity_", true);
90 
91  if (_solve_temp)
92  {
93  _T_init = ic_params.get<double>("Temperature");
94  this->addEvaluatedField(_temperature);
95  this->addUnsharedField(_temperature.fieldTag().clone());
96  }
97 
98  this->setName("Turbulent Channel Initial Condition "
99  + std::to_string(num_space_dim) + "D");
100 }
101 
102 //---------------------------------------------------------------------------//
103 template<class EvalType, class Traits, int NumSpaceDim>
104 void IncompressibleTurbulentChannel<EvalType, Traits, NumSpaceDim>::
105  postRegistrationSetup(typename Traits::SetupData sd,
106  PHX::FieldManager<Traits>&)
107 {
108  _basis_index = panzer::getPureBasisIndex(
109  _basis_name, (*sd.worksets_)[0], this->wda);
110 }
111 
112 //---------------------------------------------------------------------------//
113 template<class EvalType, class Traits, int NumSpaceDim>
114 void IncompressibleTurbulentChannel<EvalType, Traits, NumSpaceDim>::evaluateFields(
115  typename Traits::EvalData workset)
116 {
117  _basis_coords = this->wda(workset).bases[_basis_index]->basis_coordinates;
118  auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
119  workset.num_cells);
120  Kokkos::parallel_for(this->getName(), policy, *this);
121 }
122 
123 //---------------------------------------------------------------------------//
124 template<class EvalType, class Traits, int NumSpaceDim>
125 KOKKOS_INLINE_FUNCTION void
126 IncompressibleTurbulentChannel<EvalType, Traits, NumSpaceDim>::operator()(
127  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
128 {
129  const int cell = team.league_rank();
130  const int num_basis = _velocity[0].extent(1);
131  const double abs_tol = 1e-10;
132 
133  using Kokkos::log;
134  using Kokkos::pow;
135  using Kokkos::sin;
136 
137  Kokkos::parallel_for(
138  Kokkos::TeamThreadRange(team, 0, num_basis), [&](const int basis) {
139  // Calculate non-dimensional wall distance
140  const double y_plus
141  = _u_tau
142  * (_h
143  - SmoothMath::abs(_basis_coords(cell, basis, 1), abs_tol))
144  / _nu;
145 
146  // Set linear velocity in viscous sublayer
147  if (y_plus < 11.06)
148  {
149  _velocity[0](cell, basis) = y_plus * _u_tau;
150  }
151  // Set log velocity in log layer
152  else
153  {
154  _velocity[0](cell, basis) = _u_tau
155  * (1.0 / 0.41 * log(y_plus) + 5.2);
156  }
157 
158  // Set base velocity values in y- and z-directions
159  _velocity[1](cell, basis) = 0.0;
160  if (num_space_dim == 3)
161  _velocity[2](cell, basis) = 0.0;
162 
163  // Add random streamwise perturbations
164  if (_add_rands)
165  {
166  _velocity[0](cell, basis) += 0.1 * _rands(cell, basis) * _U_0;
167  }
168 
169  // Add Fourier modes
170  for (int m = 1; m <= _nb_modes; ++m)
171  {
172  _velocity[0](cell, basis)
173  += 0.1
174  * (pow(_h, 2.0)
175  - pow(_basis_coords(cell, basis, 1), 2.0))
176  * sin(4.0 * m * pi * _basis_coords(cell, basis, 2)
177  / _L_z);
178 
179  if (num_space_dim == 3)
180  {
181  _velocity[2](cell, basis)
182  += 0.1 * _U_0
183  * (pow(_h, 2.0)
184  - pow(_basis_coords(cell, basis, 1), 2.0))
185  * sin(4.0 * m * pi * _basis_coords(cell, basis, 0)
186  / _L_x);
187  }
188  }
189 
190  // Set uniform temperature and pressure
191  _lagrange_pressure(cell, basis) = 0.0;
192 
193  if (_solve_temp)
194  {
195  _temperature(cell, basis) = _T_init;
196  }
197  });
198 }
199 
200 //---------------------------------------------------------------------------//
201 
202 } // end namespace InitialCondition
203 } // end namespace VertexCFD
204 
205 #endif // end
206  // VERTEXCFD_INITIALCONDITION_INCOMPRESSIBLETURBULENTCHANNEL_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23