22#ifndef INCLUDE_EXADG_OPERATORS_GRID_RELATED_TIME_STEP_RESTRICTIONS_H_
23#define INCLUDE_EXADG_OPERATORS_GRID_RELATED_TIME_STEP_RESTRICTIONS_H_
26#include <deal.II/base/function.h>
27#include <deal.II/lac/la_parallel_vector.h>
30#include <exadg/functions_and_boundary_conditions/evaluate_functions.h>
31#include <exadg/grid/calculate_characteristic_element_length.h>
32#include <exadg/matrix_free/integrators.h>
33#include <exadg/time_integration/enum_types.h>
48calculate_time_step_max_efficiency(
double const h,
49 unsigned int const fe_degree,
50 unsigned int const order_time_integration)
52 double const exponent = (double)(fe_degree + 1) / order_time_integration;
53 double const time_step = std::pow(h, exponent);
64calculate_const_time_step_diff(
double const diffusivity,
65 double const global_min_cell_diameter,
66 unsigned int const fe_degree,
67 double const exponent_fe_degree = 3.0)
69 double const time_step =
70 pow(global_min_cell_diameter, 2.0) / pow(fe_degree, exponent_fe_degree) / diffusivity;
81calculate_max_velocity(dealii::Triangulation<dim>
const & triangulation,
82 std::shared_ptr<dealii::Function<dim>> velocity,
84 MPI_Comm
const & mpi_comm)
86 double U = 0.0, max_U = std::numeric_limits<double>::min();
88 dealii::Tensor<1, dim, double> vel;
89 velocity->set_time(time);
91 for(
auto const & cell : triangulation.active_cell_iterators())
93 if(cell->is_locally_owned())
96 dealii::Point<dim> point = cell->center();
98 for(
unsigned int d = 0; d < dim; ++d)
99 vel[d] = velocity->value(point, d);
106 double const global_max_U = dealii::Utilities::MPI::max(max_U, mpi_comm);
119template<
int dim,
typename value_type>
121calculate_time_step_cfl_local(dealii::MatrixFree<dim, value_type>
const & data,
122 unsigned int const dof_index,
123 unsigned int const quad_index,
124 std::shared_ptr<dealii::Function<dim>>
const velocity,
126 unsigned int const degree,
127 double const exponent_fe_degree,
128 CFLConditionType
const cfl_condition_type,
129 MPI_Comm
const & mpi_comm)
131 CellIntegrator<dim, dim, value_type> fe_eval(data, dof_index, quad_index);
133 double new_time_step = std::numeric_limits<double>::max();
135 double const cfl_p = 1.0 / pow(degree, exponent_fe_degree);
138 for(
unsigned int cell = 0; cell < data.n_cell_batches(); ++cell)
140 dealii::VectorizedArray<value_type> delta_t_cell =
141 dealii::make_vectorized_array<value_type>(std::numeric_limits<value_type>::max());
143 fe_eval.reinit(cell);
146 for(
unsigned int q = 0; q < fe_eval.n_q_points; ++q)
148 dealii::Point<dim, dealii::VectorizedArray<value_type>> q_point = fe_eval.quadrature_point(q);
150 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> u_x =
151 FunctionEvaluator<1, dim, value_type>::value(*velocity, q_point, time);
152 dealii::Tensor<2, dim, dealii::VectorizedArray<value_type>> invJ =
153 fe_eval.inverse_jacobian(q);
154 invJ = transpose(invJ);
155 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> ut_xi = invJ * u_x;
157 if(cfl_condition_type == CFLConditionType::VelocityNorm)
159 delta_t_cell = std::min(delta_t_cell, cfl_p / ut_xi.norm());
161 else if(cfl_condition_type == CFLConditionType::VelocityComponents)
163 for(
unsigned int d = 0; d < dim; ++d)
164 delta_t_cell = std::min(delta_t_cell, cfl_p / (std::abs(ut_xi[d])));
168 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
173 double dt = std::numeric_limits<double>::max();
174 for(
unsigned int v = 0; v < dealii::VectorizedArray<value_type>::size(); ++v)
176 dt = std::min(dt, (
double)delta_t_cell[v]);
179 new_time_step = std::min(new_time_step, dt);
183 new_time_step = dealii::Utilities::MPI::min(new_time_step, mpi_comm);
185 return new_time_step;
192template<
int dim,
typename value_type>
194calculate_time_step_cfl_local(
195 dealii::MatrixFree<dim, value_type>
const & data,
196 unsigned int const dof_index,
197 unsigned int const quad_index,
198 dealii::LinearAlgebra::distributed::Vector<value_type>
const & velocity,
199 unsigned int const degree,
200 double const exponent_fe_degree,
201 CFLConditionType
const cfl_condition_type,
202 MPI_Comm
const & mpi_comm)
204 CellIntegrator<dim, dim, value_type> fe_eval(data, dof_index, quad_index);
206 double new_time_step = std::numeric_limits<double>::max();
208 double const cfl_p = 1.0 / pow(degree, exponent_fe_degree);
211 for(
unsigned int cell = 0; cell < data.n_cell_batches(); ++cell)
213 dealii::VectorizedArray<value_type> delta_t_cell =
214 dealii::make_vectorized_array<value_type>(std::numeric_limits<value_type>::max());
216 dealii::Tensor<2, dim, dealii::VectorizedArray<value_type>> invJ;
217 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> u_x;
218 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> ut_xi;
220 fe_eval.reinit(cell);
221 fe_eval.read_dof_values(velocity);
222 fe_eval.evaluate(dealii::EvaluationFlags::values);
225 for(
unsigned int q = 0; q < fe_eval.n_q_points; ++q)
227 u_x = fe_eval.get_value(q);
228 invJ = fe_eval.inverse_jacobian(q);
229 invJ = transpose(invJ);
232 if(cfl_condition_type == CFLConditionType::VelocityNorm)
234 delta_t_cell = std::min(delta_t_cell, cfl_p / ut_xi.norm());
236 else if(cfl_condition_type == CFLConditionType::VelocityComponents)
238 for(
unsigned int d = 0; d < dim; ++d)
239 delta_t_cell = std::min(delta_t_cell, cfl_p / (std::abs(ut_xi[d])));
243 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
248 double dt = std::numeric_limits<double>::max();
249 for(
unsigned int v = 0; v < dealii::VectorizedArray<value_type>::size(); ++v)
251 dt = std::min(dt, (
double)delta_t_cell[v]);
254 new_time_step = std::min(new_time_step, dt);
258 new_time_step = dealii::Utilities::MPI::min(new_time_step, mpi_comm);
269 new_time_step = dealii::Utilities::truncate_to_n_digits(new_time_step, 4);
271 return new_time_step;
279template<
int dim,
typename value_type>
281calculate_cfl(dealii::LinearAlgebra::distributed::Vector<value_type> & cfl,
282 dealii::Triangulation<dim>
const & triangulation,
283 dealii::MatrixFree<dim, value_type>
const & data,
284 unsigned int const dof_index,
285 unsigned int const quad_index,
286 dealii::LinearAlgebra::distributed::Vector<value_type>
const & velocity,
287 double const time_step,
288 unsigned int const degree,
289 double const exponent_fe_degree)
291 CellIntegrator<dim, dim, value_type> fe_eval(data, dof_index, quad_index);
293 unsigned int const n_active_cells = triangulation.n_active_cells();
295 cfl.reinit(n_active_cells);
297 for(
unsigned int cell = 0; cell < data.n_cell_batches(); ++cell)
299 fe_eval.reinit(cell);
300 fe_eval.read_dof_values(velocity);
301 fe_eval.evaluate(dealii::EvaluationFlags::values);
303 dealii::VectorizedArray<value_type> u_va =
304 dealii::make_vectorized_array<value_type>(std::numeric_limits<value_type>::min());
306 dealii::Tensor<2, dim, dealii::VectorizedArray<value_type>> invJ;
307 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> u_x;
308 dealii::Tensor<1, dim, dealii::VectorizedArray<value_type>> ut_xi;
311 for(
unsigned int q = 0; q < fe_eval.n_q_points; ++q)
313 u_x = fe_eval.get_value(q);
314 invJ = fe_eval.inverse_jacobian(q);
315 invJ = transpose(invJ);
318 u_va = std::max(u_va, ut_xi.norm());
322 for(
unsigned int v = 0; v < data.n_active_entries_per_cell_batch(cell); ++v)
324 cfl[data.get_cell_iterator(cell, v)->active_cell_index()] =
325 u_va[v] * time_step * pow(degree, exponent_fe_degree);