181 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &normal)
const
184 const auto velocity_m = calculate_velocity<dim, number>(u_m);
185 const auto velocity_p = calculate_velocity<dim, number>(u_p);
187 const auto flux_m = calculate_convective_flux(u_m);
188 const auto flux_p = calculate_convective_flux(u_p);
190 const auto sound_speed_p = material.eos_utils->calculate_speed_of_sound(u_p);
191 const auto sound_speed_m = material.eos_utils->calculate_speed_of_sound(u_m);
193 switch (flow_data.numerical_flux_type)
195 case NumericalFluxType::lax_friedrichs_modified: {
196 const auto sound_speed_p2 = sound_speed_p * sound_speed_p;
197 const auto sound_speed_m2 = sound_speed_m * sound_speed_m;
200 0.5 * std::sqrt(std::max(velocity_p.norm_square() + sound_speed_p2,
201 velocity_m.norm_square() + sound_speed_m2));
203 return contract_average_tensor_with_vector<n_conserved_variables<dim>,
205 dealii::VectorizedArray<number>>(flux_m,
208 0.5 * lambda * (u_m - u_p);
210 case NumericalFluxType::lax_friedrichs_exact: {
211 const auto lambda = std::max(std::abs(velocity_p * normal) + sound_speed_p,
212 std::abs(velocity_m * normal) + sound_speed_m);
214 return contract_average_tensor_with_vector<n_conserved_variables<dim>,
216 dealii::VectorizedArray<number>>(flux_m,
219 0.5 * lambda * (u_m - u_p);
221 case NumericalFluxType::harten_lax_vanleer: {
222 const auto avg_velocity_normal = 0.5 * ((velocity_m + velocity_p) * normal);
223 const auto avg_c = std::abs(0.5 * (sound_speed_m + sound_speed_p));
224 const dealii::VectorizedArray<number> s_pos =
225 std::max(dealii::VectorizedArray<number>(), avg_velocity_normal + avg_c);
226 const dealii::VectorizedArray<number> s_neg =
227 std::min(dealii::VectorizedArray<number>(), avg_velocity_normal - avg_c);
228 const dealii::VectorizedArray<number> inverse_s =
229 dealii::VectorizedArray<number>(1.) / (s_pos - s_neg);
233 contract_tensor_with_vector<n_conserved_variables<dim>, dim, number>(flux_m,
238 s_pos * s_neg * (u_m - u_p));
241 Assert(
false, dealii::ExcNotImplemented());
288 dealii::VectorizedArray<number> rho_inv = 1.0 / w_q[0];
289 dealii::VectorizedArray<number> momentum_norm_squared = 0.0;
290 dealii::VectorizedArray<number> momentum_times_delta_momentum_squared = 0.0;
291 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> momentum;
292 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> delta_momentum;
293 for (
unsigned int i = 1; i < dim + 1; ++i)
295 momentum_norm_squared += w_q[i] * w_q[i];
296 momentum_times_delta_momentum_squared += delta_w_q[i] * w_q[i];
297 momentum[i - 1] = w_q[i];
298 delta_momentum[i - 1] = delta_w_q[i];
302 for (
unsigned int dimension = 0; dimension < dim; ++dimension)
303 convective_differential_change[0][dimension] = delta_w_q[dimension + 1];
306 dealii::Tensor<1, dim, dealii::Tensor<1, dim, dealii::VectorizedArray<number>>> helper;
308 helper -= rho_inv * rho_inv * delta_w_q[0] *
309 dyadic_product<dim, dim, dealii::VectorizedArray<number>>(&w_q[1], &w_q[1]);
310 helper += rho_inv * rho_inv * rs_div_c * momentum_norm_squared * delta_w_q[0] * 0.5 *
311 identity<dim, dealii::VectorizedArray<number>>();
314 rho_inv * dyadic_product<dim, dim, dealii::VectorizedArray<number>>(&delta_w_q[1], &w_q[1]);
316 rho_inv * dyadic_product<dim, dim, dealii::VectorizedArray<number>>(&w_q[1], &delta_w_q[1]);
317 helper -= rs_div_c * rho_inv * momentum_times_delta_momentum_squared *
318 identity<dim, dealii::VectorizedArray<number>>();
320 helper += rs_div_c * delta_w_q[dim + 1] * identity<dim, dealii::VectorizedArray<number>>();
322 for (
unsigned int i = 0; i < dim; ++i)
324 convective_differential_change[i + 1] += helper[i];
328 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> helper_energy;
330 helper_energy -= (w_q[dim + 1] + rs_div_c * (w_q[dim + 1] - rho_inv * momentum_norm_squared)) *
331 rho_inv * rho_inv * delta_w_q[0] * momentum;
334 (w_q[dim + 1] + rs_div_c * (w_q[dim + 1] - 0.5 * rho_inv * momentum_norm_squared)) * rho_inv *
337 rs_div_c * momentum_times_delta_momentum_squared * rho_inv * rho_inv * momentum;
339 helper_energy += (1 + rs_div_c) * delta_w_q[dim + 1] * rho_inv * momentum;
340 convective_differential_change[dim + 1] = helper_energy;
342 return convective_differential_change;
349 const std::pair<ConservedVariables, ConservedVariables> &w_q,
350 const std::pair<ConservedVariables, ConservedVariables> &delta_w_q,
351 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &normal)
const
365 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &)>
366 compute_lambda_times_jump;
369 switch (flow_data.numerical_flux_type)
371 case NumericalFluxType::lax_friedrichs_exact: {
372 compute_lambda_times_jump =
378 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &normal)
380 const auto velocity_m = calculate_velocity<dim, number>(w_m);
381 const auto velocity_p = calculate_velocity<dim, number>(w_p);
383 const auto lambda = std::max(std::abs(velocity_p * normal) +
384 material.eos_utils->calculate_speed_of_sound(w_p),
385 std::abs(velocity_m * normal) +
386 material.eos_utils->calculate_speed_of_sound(w_m));
387 return lambda * (delta_w_m - delta_w_p);
391 case NumericalFluxType::lax_friedrichs_modified: {
392 compute_lambda_times_jump =
397 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &)
399 const auto velocity_m = calculate_velocity<dim, number>(w_m);
400 const auto velocity_p = calculate_velocity<dim, number>(w_p);
402 const auto pressure_m = material.eos_utils->calculate_thermodynamic_pressure(w_m);
403 const auto pressure_p = material.eos_utils->calculate_thermodynamic_pressure(w_p);
406 0.5 * std::sqrt(std::max(velocity_p.norm_square() +
407 std::abs(material.data.gamma * pressure_p / w_p[0]),
408 velocity_m.norm_square() +
409 std::abs(material.data.gamma * pressure_m / w_m[0])));
410 return lambda * (delta_w_m - delta_w_p);
415 DEAL_II_ASSERT_UNREACHABLE();
420 constexpr number epsilon = 1e-3;
421 constexpr number epsilon_inv = 1e3;
422 switch (flow_data.linearization_jump_convective_flux)
424 case LinearizedConvectiveFluxJumpType::complete_fd: {
426 compute_lambda_times_jump(w_p, w_m, w_p, w_m, normal),
429 compute_lambda_times_jump(w_p + epsilon * delta_w_p,
430 w_m + epsilon * delta_w_m,
431 w_p + epsilon * delta_w_p,
432 w_m + epsilon * delta_w_m,
437 case LinearizedConvectiveFluxJumpType::lambda_fd: {
439 0.5 * compute_lambda_times_jump(w_p, w_m, delta_w_p, delta_w_m, normal), normal);
441 auto helper = compute_lambda_times_jump(
442 w_p + epsilon * delta_w_p, w_m + epsilon * delta_w_m, w_p, w_m, normal);
443 helper -= compute_lambda_times_jump(w_p, w_m, w_p, w_m, normal);
447 case LinearizedConvectiveFluxJumpType::analytic: {
449 0.5 * compute_lambda_times_jump(w_p, w_m, delta_w_p, delta_w_m, normal), normal);
451 const auto linearize_speed_of_sound =
454 const dealii::VectorizedArray<number> &c,
455 const dealii::VectorizedArray<number> &) -> dealii::VectorizedArray<number> {
456 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> m_q;
457 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> delta_m_q;
458 for (
unsigned int i = 0; i < dim; ++i)
461 delta_m_q[i] = delta_w_q[i + 1];
463 dealii::VectorizedArray<number> rho_inv = 1. / w_q[0];
464 dealii::VectorizedArray<number> lin_c =
465 delta_w_q[0] / (2.0 * c) * material.data.gamma * rho_inv * rho_inv * rs_div_c *
466 (rho_inv * m_q * m_q - w_q[dim + 1]);
468 material.data.gamma / (2.0 * c) * rho_inv * rho_inv * rs_div_c * m_q * delta_m_q;
469 lin_c += material.data.gamma / (2.0 * c) * rho_inv * rs_div_c * delta_w_q[dim + 1];
473 const auto norm_lin_velocity =
476 const dealii::Tensor<1, dim, dealii::VectorizedArray<number>> &normal)
477 -> dealii::VectorizedArray<number> {
478 auto rho_inv = 1. / w_q[dim + 1];
479 auto u = calculate_velocity<dim, number>(w_q);
480 dealii::Tensor<1, dim, dealii::VectorizedArray<number>> delta_m_q;
481 for (
unsigned int i = 0; i < dim; ++i)
482 delta_m_q[i] = delta_w_q[i + 1];
483 auto lin_velocity = delta_m_q * rho_inv - u * rho_inv * delta_w_q[0];
484 return lin_velocity * normal;
489 const dealii::VectorizedArray<number> &a) ->
const dealii::VectorizedArray<number> {
490 return dealii::compare_and_apply_mask<dealii::SIMDComparison::greater_than>(
491 a, dealii::VectorizedArray<number>(0.0), 1.0, -1.0);
494 const auto velocity_m = calculate_velocity<dim, number>(w_m);
495 const auto velocity_p = calculate_velocity<dim, number>(w_p);
497 const auto pressure_m = material.eos_utils->calculate_thermodynamic_pressure(w_m);
498 const auto pressure_p = material.eos_utils->calculate_thermodynamic_pressure(w_p);
500 const auto speed_of_sound_m = material.eos_utils->calculate_speed_of_sound(w_m);
501 const auto speed_of_sound_p = material.eos_utils->calculate_speed_of_sound(w_p);
503 const auto lin_lambda_p =
504 signum(velocity_p * normal) * norm_lin_velocity(w_p, delta_w_p, normal) +
505 linearize_speed_of_sound(w_p, delta_w_p, speed_of_sound_p, pressure_p);
506 const auto lin_lambda_m =
507 signum(velocity_m * normal) * norm_lin_velocity(w_m, delta_w_m, normal) +
508 linearize_speed_of_sound(w_m, delta_w_m, speed_of_sound_m, pressure_m);
510 const auto lin_lambda =
511 dealii::compare_and_apply_mask<dealii::SIMDComparison::greater_than>(
512 velocity_p.norm() + speed_of_sound_p,
513 velocity_m.norm() + speed_of_sound_m,
517 for (
unsigned int i = 0; i < n_conserved_variables<dim>; ++i)
518 flux[i] += 0.5 * lin_lambda * (w_m[i] - w_p[i]) * normal;
526 "The provided linearization scheme of the jump operator term in the convective"
527 " numerical flux is not supported."));