1 #ifndef VERTEXCFD_CLOSURE_METHODMANUFACTUREDSOLUTIONSOURCE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_METHODMANUFACTUREDSOLUTIONSOURCE_IMPL_HPP
4 #include "utils/VertexCFD_Utils_VectorField.hpp"
6 #include "utils/VertexCFD_Utils_Constants.hpp"
8 #include <Panzer_HierarchicParallelism.hpp>
9 #include <Panzer_Workset_Utilities.hpp>
14 #include <type_traits>
18 namespace ClosureModel
21 template<
class EvalType,
class Traits,
int NumSpaceDim>
22 MethodManufacturedSolutionSource<EvalType, Traits, NumSpaceDim>::
23 MethodManufacturedSolutionSource(
const panzer::IntegrationRule& ir,
24 const bool build_viscous_flux,
25 const Teuchos::ParameterList& closure_params)
26 : _continuity_mms_source(
"MMS_SOURCE_continuity", ir.dl_scalar)
27 , _energy_mms_source(
"MMS_SOURCE_energy", ir.dl_scalar)
28 , _ir_degree(ir.cubature_degree)
29 , _build_viscous_flux(build_viscous_flux)
30 , _rho(closure_params.get<double>(
"Density"))
31 , _nu(closure_params.get<double>(
"Kinematic Viscosity"))
34 this->addEvaluatedField(_continuity_mms_source);
35 Utils::addEvaluatedVectorField(
36 *
this, ir.dl_scalar, _momentum_mms_source,
"MMS_SOURCE_momentum_");
37 this->addEvaluatedField(_energy_mms_source);
40 _phi_coeff[0] = 0.0125;
44 _phi_coeff[4] = 0.125;
47 _vel_coeff[0][0] = 0.0125;
48 _vel_coeff[0][1] = 0.08;
49 _vel_coeff[0][2] = 0.125;
50 _vel_coeff[0][3] = 0.0;
51 _vel_coeff[0][4] = 0.125;
52 _vel_coeff[0][5] = 0.25;
54 _vel_coeff[1][0] = 0.0375;
55 _vel_coeff[1][1] = 1.125;
56 _vel_coeff[1][2] = 0.25;
57 _vel_coeff[1][3] = 0.0;
58 _vel_coeff[1][4] = 0.375;
59 _vel_coeff[1][5] = 0.5;
68 if (num_space_dim == 3)
70 _phi_coeff[6] = 0.375;
73 _vel_coeff[0][6] = 0.25;
74 _vel_coeff[0][7] = 0.0;
76 _vel_coeff[1][6] = 0.25;
77 _vel_coeff[1][7] = 0.5;
79 _vel_coeff[2][0] = 0.025;
80 _vel_coeff[2][1] = 0.0;
81 _vel_coeff[2][2] = 0.125;
82 _vel_coeff[2][3] = 1.0;
83 _vel_coeff[2][4] = 0.25;
84 _vel_coeff[2][5] = 0.25;
85 _vel_coeff[2][6] = 0.25;
86 _vel_coeff[2][7] = 0.25;
92 this->setName(
"Method of Manufactured Solution Source "
93 + std::to_string(num_space_dim) +
"D");
97 template<
class EvalType,
class Traits,
int NumSpaceDim>
98 void MethodManufacturedSolutionSource<EvalType, Traits, NumSpaceDim>::
99 postRegistrationSetup(
typename Traits::SetupData sd,
100 PHX::FieldManager<Traits>&)
102 _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
106 template<
class EvalType,
class Traits,
int NumSpaceDim>
107 void MethodManufacturedSolutionSource<EvalType, Traits, NumSpaceDim>::evaluateFields(
108 typename Traits::EvalData workset)
110 _ip_coords = workset.int_rules[_ir_index]->ip_coordinates;
111 const Kokkos::RangePolicy<PHX::Device> policy(0, workset.num_cells);
112 Kokkos::parallel_for(this->getName(), policy, *
this);
116 template<
class EvalType,
class Traits,
int NumSpaceDim>
118 KOKKOS_INLINE_FUNCTION T
119 MethodManufacturedSolutionSource<EvalType, Traits, NumSpaceDim>::set_function(
120 const Kokkos::Array<double, num_coeff>& coeff,
121 const Kokkos::Array<T, num_space_dim>& x)
const
128 for (
int i = 0; i < num_space_dim; ++i)
129 val *= sin(2.0 * pi * coeff[2 * (i + 1)]
130 * (x[i] - coeff[2 * (i + 1) + 1]));
136 template<
class EvalType,
class Traits,
int NumSpaceDim>
137 KOKKOS_INLINE_FUNCTION
void
138 MethodManufacturedSolutionSource<EvalType, Traits, NumSpaceDim>::operator()(
139 const int cell)
const
141 const int num_point = _continuity_mms_source.extent(1);
143 const double third = 1.0 / 3.0;
145 for (
int point = 0; point < num_point; ++point)
147 using diff1_type = Sacado::Fad::SFad<scalar_type, num_space_dim>;
148 using diff2_type = Sacado::Fad::SFad<diff1_type, num_space_dim>;
151 Kokkos::Array<diff1_type, num_space_dim> diff1_x;
152 Kokkos::Array<diff2_type, num_space_dim> diff2_x;
155 for (
int i = 0; i < num_space_dim; ++i)
156 diff1_x[i] = _ip_coords(cell, point, i);
159 for (
int i = 0; i < num_space_dim; ++i)
161 diff1_x[i].diff(i, num_space_dim);
162 diff2_x[i] = diff1_x[i];
165 for (
int i = 0; i < num_space_dim; ++i)
166 diff2_x[i].diff(i, num_space_dim);
169 Kokkos::Array<diff2_type, num_space_dim> diff2_vel;
170 for (
int i = 0; i < num_space_dim; ++i)
171 diff2_vel[i] = set_function(_vel_coeff[i], diff2_x);
172 const diff2_type diff2_T = set_function(_T_coeff, diff2_x);
175 Kokkos::Array<Kokkos::Array<diff1_type, num_space_dim>, num_space_dim>
177 Kokkos::Array<diff1_type, num_space_dim> diff1_grad_T;
178 for (
int i = 0; i < num_space_dim; ++i)
180 for (
int j = 0; j < num_space_dim; ++j)
181 diff1_grad_u[i][j] = diff2_vel[i].fastAccessDx(j);
183 diff1_grad_T[i] = diff2_T.fastAccessDx(i);
186 diff1_type diff1_tr_grad_u = 0.0;
187 for (
int i = 0; i < num_space_dim; ++i)
188 diff1_tr_grad_u += diff1_grad_u[i][i];
189 diff1_tr_grad_u *= third;
192 const diff1_type diff1_phi = set_function(_phi_coeff, diff1_x);
194 Kokkos::Array<diff1_type, num_space_dim> diff1_vel;
195 for (
int i = 0; i < num_space_dim; ++i)
196 diff1_vel[i] = diff2_vel[i].val();
197 const diff1_type diff1_T = diff2_T.val();
202 Kokkos::Array<Kokkos::Array<diff1_type, num_space_dim>, num_conserve>
206 for (
int i = 0; i < num_space_dim; ++i)
207 conv_flux[0][i] = diff1_vel[i];
210 for (
int i = 0; i < num_space_dim; ++i)
211 for (
int j = 0; j < num_space_dim; ++j)
213 conv_flux[i + 1][j] = diff1_vel[i] * diff1_vel[j];
215 conv_flux[i + 1][j] += diff1_phi;
219 for (
int i = 0; i < num_space_dim; ++i)
221 conv_flux[num_conserve - 1][i] = diff1_T * diff1_vel[i];
225 Kokkos::Array<Kokkos::Array<diff1_type, num_space_dim>, num_conserve> flux;
226 for (
int i = 0; i < num_conserve; ++i)
227 for (
int j = 0; j < num_space_dim; ++j)
228 flux[i][j] = conv_flux[i][j];
233 if (_build_viscous_flux)
236 Kokkos::Array<Kokkos::Array<diff1_type, num_space_dim>, num_space_dim>
238 for (
int i = 0; i < num_space_dim; ++i)
239 for (
int j = 0; j < num_space_dim; ++j)
244 * (diff1_grad_u[i][j] - diff1_tr_grad_u);
247 = _nu * (diff1_grad_u[i][j] + diff1_grad_u[j][i]);
251 Kokkos::Array<Kokkos::Array<diff1_type, num_space_dim>, num_conserve>
255 for (
int i = 0; i < num_space_dim; ++i)
256 visc_flux[0][i] = 0.0;
259 for (
int i = 0; i < num_space_dim; ++i)
260 for (
int j = 0; j < num_space_dim; ++j)
261 visc_flux[i + 1][j] = diff1_tau[i][j];
264 for (
int i = 0; i < num_space_dim; ++i)
266 diff1_type viscous_work = 0.0;
267 for (
int j = 0; j < num_space_dim; ++j)
268 viscous_work += diff1_vel[j] * diff1_tau[i][j];
270 visc_flux[num_conserve - 1][i] = viscous_work
271 + _kappa * diff1_grad_T[i];
275 for (
int i = 0; i < num_conserve; ++i)
276 for (
int j = 0; j < num_space_dim; ++j)
277 flux[i][j] -= visc_flux[i][j];
281 scalar_type continuity_sum = 0.0;
282 Kokkos::Array<scalar_type, num_space_dim> mom_sum;
283 for (
int i = 0; i < num_space_dim; ++i)
285 scalar_type energy_sum = 0.0;
286 for (
int i = 0; i < num_space_dim; ++i)
288 continuity_sum += flux[0][i].fastAccessDx(i);
289 for (
int j = 0; j < num_space_dim; ++j)
290 mom_sum[i] += flux[i + 1][j].fastAccessDx(j);
293 energy_sum += flux[num_conserve - 1][i].fastAccessDx(i);
296 _continuity_mms_source(cell, point) = continuity_sum;
297 for (
int i = 0; i < num_space_dim; ++i)
298 _momentum_mms_source[i](cell, point) = mom_sum[i];
299 _energy_mms_source(cell, point) = energy_sum;
308 #endif // end VERTEXCFD_CLOSURE_METHODMANUFACTUREDSOLUTIONSOURCE_IMPL_HPP