hyper.deal
Loading...
Searching...
No Matches
cfl.h
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2020 by the hyper.deal authors
4//
5// This file is part of the hyper.deal library.
6//
7// The hyper.deal library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 3.0 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.MD at
12// the top level directory of hyper.deal.
13//
14// ---------------------------------------------------------------------
15
16#ifndef HYPERDEAL_CFL
17#define HYPERDEAL_CFL
18
19#include <hyper.deal/base/config.h>
20
21#include <deal.II/fe/fe_dgq.h>
22#include <deal.II/fe/fe_values.h>
23
24namespace hyperdeal
25{
26 namespace advection
27 {
31 template <int dim, typename Number>
32 Number
33 compute_critical_time_step(dealii::DoFHandler<dim> & dof_handler,
34 dealii::Tensor<1, dim, Number> u,
35 const unsigned int degree,
36 const unsigned int n_points,
37 MPI_Comm comm);
38
42 template <int dim_x, int dim_v, typename Number>
43 Number
44 compute_critical_time_step(dealii::DoFHandler<dim_x> &dof_handler_x,
45 dealii::DoFHandler<dim_v> &dof_handler_v,
46 dealii::Tensor<1, dim_x + dim_v, Number> uu,
47 const unsigned int degree_x,
48 const unsigned int n_points_x,
49 MPI_Comm comm_row,
50 const unsigned int degree_v,
51 const unsigned int n_points_v,
52 MPI_Comm comm_column);
53
54
55
56 template <int dim, typename Number>
57 Number
58 compute_critical_time_step(dealii::DoFHandler<dim> & dof_handler,
59 dealii::Tensor<1, dim, Number> u,
60 const unsigned int degree,
61 const unsigned int n_points,
62 MPI_Comm comm)
63 {
64 dealii::FE_DGQ<dim> fe(degree);
65 dealii::QGauss<dim> quad(n_points);
66
67 dealii::FEValues<dim> fe_values(fe,
68 quad,
69 dealii::update_inverse_jacobians);
70
71 Number v_max = 0.0;
72
73 for (auto &cell : dof_handler.active_cell_iterators())
74 if (cell->is_locally_owned())
75 {
76 fe_values.reinit(cell);
77 for (unsigned int q = 0; q < quad.size(); ++q)
78 {
79 dealii::Tensor<1, dim, Number> v;
80 for (unsigned int i = 0; i < dim; i++)
81 for (unsigned int j = 0; j < dim; j++)
82 v[j] += fe_values.inverse_jacobian(q)[i][j] * u[i];
83
84 for (unsigned int i = 0; i < dim; i++)
85 v_max = std::max(v_max, std::abs(v[i]));
86 }
87 }
88
89 return 1.0 / dealii::Utilities::MPI::max(v_max, comm);
90 }
91
92
93
94 template <int dim_x, int dim_v, typename Number>
95 Number
96 compute_critical_time_step(dealii::DoFHandler<dim_x> &dof_handler_x,
97 dealii::DoFHandler<dim_v> &dof_handler_v,
98 dealii::Tensor<1, dim_x + dim_v, Number> uu,
99 const unsigned int degree_x,
100 const unsigned int n_points_x,
101 MPI_Comm comm_row,
102 const unsigned int degree_v,
103 const unsigned int n_points_v,
104 MPI_Comm comm_column)
105 {
106 Number v1, v2;
107 {
108 dealii::Tensor<1, dim_x, Number> u;
109 for (unsigned int i = 0; i < dim_x; i++)
110 u[i] = uu[i];
111 v1 = compute_critical_time_step(
112 dof_handler_x, u, degree_x, n_points_x, comm_row);
113 }
114
115 {
116 dealii::Tensor<1, dim_v, Number> u;
117 for (unsigned int i = 0; i < dim_v; i++)
118 u[i] = uu[i + dim_x];
119 v2 = compute_critical_time_step(
120 dof_handler_v, u, degree_v, n_points_v, comm_column);
121 }
122
123 return std::min(v1, v2);
124 }
125
126 } // namespace advection
127} // namespace hyperdeal
128
129#endif