178 using This = Operator<dim, Number>;
180 using BlockVectorType = dealii::LinearAlgebra::distributed::BlockVector<Number>;
182 using scalar = dealii::VectorizedArray<Number>;
183 using vector = dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>;
185 using Range = std::pair<unsigned int, unsigned int>;
187 using CellIntegratorU = CellIntegrator<dim, dim, Number>;
188 using CellIntegratorP = CellIntegrator<dim, 1, Number>;
190 using FaceIntegratorU = FaceIntegrator<dim, dim, Number>;
191 using FaceIntegratorP = FaceIntegrator<dim, 1, Number>;
194 Operator() : evaluation_time(Number{0.0}), tau(Number{0.0}), gamma(Number{0.0})
199 initialize(dealii::MatrixFree<dim, Number>
const & matrix_free_in,
203 matrix_free = &matrix_free_in;
207 tau = (Number)(0.5 * data_in.speed_of_sound);
208 gamma = (Number)(0.5 / data_in.speed_of_sound);
211 if(data_in.formulation == Formulation::Weak)
213 integrator_flags_p.cell_evaluate = dealii::EvaluationFlags::values;
214 integrator_flags_p.cell_integrate = dealii::EvaluationFlags::gradients;
215 integrator_flags_p.face_evaluate = dealii::EvaluationFlags::values;
216 integrator_flags_p.face_integrate = dealii::EvaluationFlags::values;
218 integrator_flags_u.cell_evaluate = dealii::EvaluationFlags::values;
219 integrator_flags_u.cell_integrate = dealii::EvaluationFlags::gradients;
220 integrator_flags_u.face_evaluate = dealii::EvaluationFlags::values;
221 integrator_flags_u.face_integrate = dealii::EvaluationFlags::values;
223 else if(data_in.formulation == Formulation::Strong)
225 integrator_flags_p.cell_evaluate = dealii::EvaluationFlags::gradients;
226 integrator_flags_p.cell_integrate = dealii::EvaluationFlags::values;
227 integrator_flags_p.face_evaluate = dealii::EvaluationFlags::values;
228 integrator_flags_p.face_integrate = dealii::EvaluationFlags::values;
230 integrator_flags_u.cell_evaluate = dealii::EvaluationFlags::gradients;
231 integrator_flags_u.cell_integrate = dealii::EvaluationFlags::values;
232 integrator_flags_u.face_evaluate = dealii::EvaluationFlags::values;
233 integrator_flags_u.face_integrate = dealii::EvaluationFlags::values;
235 else if(data_in.formulation == Formulation::SkewSymmetric)
237 integrator_flags_p.cell_evaluate = dealii::EvaluationFlags::gradients;
238 integrator_flags_p.cell_integrate = dealii::EvaluationFlags::gradients;
239 integrator_flags_p.face_evaluate = dealii::EvaluationFlags::values;
240 integrator_flags_p.face_integrate = dealii::EvaluationFlags::values;
242 integrator_flags_u.cell_evaluate = dealii::EvaluationFlags::values;
243 integrator_flags_u.cell_integrate = dealii::EvaluationFlags::values;
244 integrator_flags_u.face_evaluate = dealii::EvaluationFlags::values;
245 integrator_flags_u.face_integrate = dealii::EvaluationFlags::values;
249 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
254 evaluate(BlockVectorType & dst, BlockVectorType
const & src,
double const time)
const
256 do_evaluate(dst, src, time,
true);
260 evaluate_add(BlockVectorType & dst, BlockVectorType
const & src,
double const time)
const
262 do_evaluate(dst, src, time,
true);
267 do_evaluate(BlockVectorType & dst,
268 BlockVectorType
const & src,
270 bool const zero_dst_vector)
const
272 evaluation_time = (Number)time;
274 matrix_free->loop(&This::cell_loop,
276 &This::boundary_face_loop,
281 dealii::MatrixFree<dim, Number>::DataAccessOnFaces::values,
282 dealii::MatrixFree<dim, Number>::DataAccessOnFaces::values);
286 do_cell_integral(CellIntegratorP & pressure, CellIntegratorU & velocity)
const
288 if(data.formulation == Formulation::Weak)
290 for(
unsigned int q : pressure.quadrature_point_indices())
292 vector
const flux_momentum = kernel.get_volume_flux_weak_momentum(velocity, q);
293 scalar
const flux_mass = kernel.get_volume_flux_weak_mass(pressure, q);
295 pressure.submit_gradient(flux_momentum, q);
296 velocity.submit_divergence(flux_mass, q);
299 else if(data.formulation == Formulation::Strong)
301 for(
unsigned int q : pressure.quadrature_point_indices())
303 scalar
const flux_momentum = kernel.get_volume_flux_strong_momentum(velocity, q);
304 vector
const flux_mass = kernel.get_volume_flux_strong_mass(pressure, q);
306 pressure.submit_value(flux_momentum, q);
307 velocity.submit_value(flux_mass, q);
310 else if(data.formulation == Formulation::SkewSymmetric)
312 for(
unsigned int q : pressure.quadrature_point_indices())
314 vector
const flux_momentum = kernel.get_volume_flux_weak_momentum(velocity, q);
315 vector
const flux_mass = kernel.get_volume_flux_strong_mass(pressure, q);
317 pressure.submit_gradient(flux_momentum, q);
318 velocity.submit_value(flux_mass, q);
323 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
328 template<
bool weight_neighbor,
329 typename ExteriorFaceIntegratorP,
330 typename ExteriorFaceIntegratorU>
332 do_face_integral(FaceIntegratorP & pressure_m,
333 ExteriorFaceIntegratorP & pressure_p,
334 FaceIntegratorU & velocity_m,
335 ExteriorFaceIntegratorU & velocity_p)
const
337 for(
unsigned int q : pressure_m.quadrature_point_indices())
339 scalar
const pm = pressure_m.get_value(q);
340 scalar
const pp = pressure_p.get_value(q);
341 vector
const rho_um = velocity_m.get_value(q);
342 vector
const rho_up = velocity_p.get_value(q);
343 vector
const n = pressure_m.normal_vector(q);
345 vector
const flux_momentum =
346 kernel.calculate_lax_friedrichs_flux_momentum(rho_um, rho_up, gamma, pm, pp, n);
348 scalar
const flux_mass =
349 kernel.calculate_lax_friedrichs_flux_mass(pm, pp, tau, rho_um, rho_up, n);
351 if(data.formulation == Formulation::Weak)
353 scalar
const flux_momentum_weak = flux_momentum * n;
354 vector
const flux_mass_weak = flux_mass * n;
356 pressure_m.submit_value(flux_momentum_weak, q);
357 velocity_m.submit_value(flux_mass_weak, q);
359 if constexpr(weight_neighbor)
362 pressure_p.submit_value(-flux_momentum_weak, q);
363 velocity_p.submit_value(-flux_mass_weak, q);
366 else if(data.formulation == Formulation::Strong)
368 pressure_m.submit_value((flux_momentum - rho_um) * n, q);
369 velocity_m.submit_value((flux_mass - pm) * n, q);
371 if constexpr(weight_neighbor)
374 pressure_p.submit_value((rho_up - flux_momentum) * n, q);
375 velocity_p.submit_value((pp - flux_mass) * n, q);
378 else if(data.formulation == Formulation::SkewSymmetric)
380 scalar
const flux_momentum_weak = flux_momentum * n;
382 pressure_m.submit_value(flux_momentum_weak, q);
383 velocity_m.submit_value((flux_mass - pm) * n, q);
385 if constexpr(weight_neighbor)
388 pressure_p.submit_value(-flux_momentum_weak, q);
389 velocity_p.submit_value((pp - flux_mass) * n, q);
394 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
400 cell_loop(dealii::MatrixFree<dim, Number>
const & matrix_free_in,
401 BlockVectorType & dst,
402 BlockVectorType
const & src,
403 Range
const & cell_range)
const
405 CellIntegratorP pressure(matrix_free_in, data.dof_index_pressure, data.quad_index);
406 CellIntegratorU velocity(matrix_free_in, data.dof_index_velocity, data.quad_index);
408 for(
unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
410 pressure.reinit(cell);
411 pressure.gather_evaluate(src.block(data.block_index_pressure),
412 integrator_flags_p.cell_evaluate);
414 velocity.reinit(cell);
415 velocity.gather_evaluate(src.block(data.block_index_velocity),
416 integrator_flags_u.cell_evaluate);
418 do_cell_integral(pressure, velocity);
420 pressure.integrate_scatter(integrator_flags_p.cell_integrate,
421 dst.block(data.block_index_pressure));
422 velocity.integrate_scatter(integrator_flags_u.cell_integrate,
423 dst.block(data.block_index_velocity));
428 face_loop(dealii::MatrixFree<dim, Number>
const & matrix_free_in,
429 BlockVectorType & dst,
430 BlockVectorType
const & src,
431 Range
const & face_range)
const
433 FaceIntegratorP pressure_m(matrix_free_in,
true, data.dof_index_pressure, data.quad_index);
434 FaceIntegratorP pressure_p(matrix_free_in,
false, data.dof_index_pressure, data.quad_index);
436 FaceIntegratorU velocity_m(matrix_free_in,
true, data.dof_index_velocity, data.quad_index);
437 FaceIntegratorU velocity_p(matrix_free_in,
false, data.dof_index_velocity, data.quad_index);
439 for(
unsigned int face = face_range.first; face < face_range.second; face++)
441 pressure_m.reinit(face);
442 pressure_m.gather_evaluate(src.block(data.block_index_pressure),
443 integrator_flags_p.face_evaluate);
444 pressure_p.reinit(face);
445 pressure_p.gather_evaluate(src.block(data.block_index_pressure),
446 integrator_flags_p.face_evaluate);
448 velocity_m.reinit(face);
449 velocity_m.gather_evaluate(src.block(data.block_index_velocity),
450 integrator_flags_u.face_evaluate);
451 velocity_p.reinit(face);
452 velocity_p.gather_evaluate(src.block(data.block_index_velocity),
453 integrator_flags_u.face_evaluate);
455 do_face_integral<true>(pressure_m, pressure_p, velocity_m, velocity_p);
457 pressure_m.integrate_scatter(integrator_flags_p.face_integrate,
458 dst.block(data.block_index_pressure));
459 pressure_p.integrate_scatter(integrator_flags_p.face_integrate,
460 dst.block(data.block_index_pressure));
462 velocity_m.integrate_scatter(integrator_flags_u.face_integrate,
463 dst.block(data.block_index_velocity));
464 velocity_p.integrate_scatter(integrator_flags_u.face_integrate,
465 dst.block(data.block_index_velocity));
470 boundary_face_loop(dealii::MatrixFree<dim, Number>
const & matrix_free_in,
471 BlockVectorType & dst,
472 BlockVectorType
const & src,
473 Range
const & face_range)
const
475 FaceIntegratorP pressure_m(matrix_free_in,
true, data.dof_index_pressure, data.quad_index);
478 FaceIntegratorU velocity_m(matrix_free_in,
true, data.dof_index_velocity, data.quad_index);
484 for(
unsigned int face = face_range.first; face < face_range.second; face++)
486 pressure_m.reinit(face);
487 pressure_m.gather_evaluate(src.block(data.block_index_pressure),
488 integrator_flags_p.face_evaluate);
489 pressure_p.reinit(face, evaluation_time);
491 velocity_m.reinit(face);
492 velocity_m.gather_evaluate(src.block(data.block_index_velocity),
493 integrator_flags_u.face_evaluate);
494 velocity_p.reinit(face, evaluation_time);
496 do_face_integral<false>(pressure_m, pressure_p, velocity_m, velocity_p);
498 pressure_m.integrate_scatter(integrator_flags_p.face_integrate,
499 dst.block(data.block_index_pressure));
500 velocity_m.integrate_scatter(integrator_flags_u.face_integrate,
501 dst.block(data.block_index_velocity));
507 mutable Number evaluation_time;
509 dealii::ObserverPointer<dealii::MatrixFree<dim, Number>
const> matrix_free;