1506 *
cell->get_dof_indices(dof_indices);
1507 *
std::transform(dof_indices.begin(),
1508 *
dof_indices.end(),
1509 *
dof_indices.begin(),
1511 * return partitioner->global_to_local(index);
1516 *
for (
const auto dof : dof_indices)
1517 *
dsp.add_entries(dof, dof_indices.
begin(), dof_indices.
end());
1520 *
sparsity_pattern.copy_from(
dsp);
1556 *
template <
int dim>
1559 *
bool is_artificial;
1560 *
std::vector<types::global_dof_index> local_dof_indices;
1571 * <a
href=
"https://en.wikipedia.org/wiki/Syntactic_sugar">
syntactic
1593 *
template <
typename IteratorType>
1598 *
&matrix,
it->global_index());
1612 *
template <
typename IteratorType>
1619 *
it->global_index());
1638 *
template <std::
size_t k,
typename IteratorType>
1644 *
for (
unsigned int j = 0;
j <
k; ++
j)
1685 *
for (
unsigned int l = 0;
l <
k; ++
l)
1707 *
for (
unsigned int j = 0;
j <
k; ++
j)
1708 *
result[
j] = U[
j].local_element(i);
1730 *
const unsigned int i)
1732 *
static_assert(
k ==
k2,
1733 *
"The dimensions of the input arguments must agree");
1734 *
for (
unsigned int j = 0;
j <
k; ++
j)
1735 *
U[
j].local_element(i) = tensor[
j];
1750 *
detailed in
the @
ref threads
"Parallel computing with multiple processors"
1797 *
template <
int dim>
1807 *
unsigned int dofs_per_cell =
1832 *
"offline_data - assemble lumped mass matrix, and c_ij");
1838 *
copy.is_artificial = cell->is_artificial();
1839 *
if (
copy.is_artificial)
1842 *
copy.local_boundary_normal_map.
clear();
1843 *
copy.cell_lumped_mass_matrix.reinit(dofs_per_cell, dofs_per_cell);
1847 *
const auto &fe_values = scratch.reinit(cell);
1849 *
copy.local_dof_indices.resize(dofs_per_cell);
1850 *
cell->get_dof_indices(
copy.local_dof_indices);
1852 *
std::transform(
copy.local_dof_indices.begin(),
1853 *
copy.local_dof_indices.end(),
1854 *
copy.local_dof_indices.begin(),
1856 * return partitioner->global_to_local(index);
1867 *
const auto JxW = fe_values.JxW(
q_point);
1869 *
for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1872 *
fe_values.shape_value(
j,
q_point) * JxW;
1877 *
for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1879 *
const auto value = fe_values.shape_value(i,
q_point);
1880 *
for (
unsigned int d = 0;
d < dim; ++
d)
1894 *
for (
const auto f : cell->face_indices())
1897 *
const auto id = face->boundary_id();
1899 *
if (!face->at_boundary())
1902 *
const auto &fe_face_values = scratch.reinit(cell, f);
1905 *
fe_face_values.get_quadrature().size();
1907 *
for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1927 *
normal += fe_face_values.normal_vector(
q) *
1928 *
fe_face_values.shape_value(
j,
q);
1931 *
const auto index =
copy.local_dof_indices[
j];
1935 *
if (cell->vertex_dof_index(v, 0) ==
1936 *
partitioner->local_to_global(
index))
1938 *
position = cell->vertex(v);
1943 *
std::get<1>(
copy.local_boundary_normal_map[index]);
1944 *
copy.local_boundary_normal_map[
index] =
1957 *
if (
copy.is_artificial)
1966 *
std::get<1>(
it.second));
1971 *
copy.cell_lumped_mass_matrix);
1973 *
for (
int k = 0;
k < dim; ++
k)
1981 *
dof_handler.end(),
1993 *
That's not what we really want: we have to normalize its entries. In
1994 * addition, we have not filled the entries of the matrix
1995 * <code>norm_matrix</code> and the vectors stored in the map
1996 * <code>OfflineData<dim>::BoundaryNormalMap</code> are not normalized.
2000 * In principle, this is just offline data, it doesn't
make much sense
2016 *
again.
That's why this is the right time to introduce them.
2020 * We have the thread parallelization capability
2021 * parallel::apply_to_subranges() that is somehow more general than the
2022 * WorkStream framework. In particular, parallel::apply_to_subranges() can
2023 * be used for our node-loops. This functionality requires four input
2024 * arguments which we explain in detail (for the specific case of our
2025 * thread-parallel node loops):
2026 * - The iterator <code>indices.begin()</code> points to a row index.
2027 * - The iterator <code>indices.end()</code> points to a numerically higher
2029 * - The function <code>on_subranges(index_begin, index_end)</code>
2030 * (where <code>index_begin</code> and <code>index_end</code>
2031 * define a sub-range within the range spanned by
2032 * the begin and end iterators defined in the two previous bullets)
2033 * applies an operation to every iterator in such subrange. We may as
2034 * well call <code>on_subranges</code> the "worker".
2035 * - Grainsize: minimum number of iterators (in this case representing
2036 * rows) processed by each thread. We decided for a minimum of 4096
2041 * A minor caveat here is that the iterators <code>indices.begin()</code>
2042 * and <code>indices.end()</code> supplied to
2043 * parallel::apply_to_subranges() have to be random access iterators:
2044 * internally, parallel::apply_to_subranges() will break the range
2045 * defined by the <code>indices.begin()</code> and
2046 * <code>indices.end()</code> iterators into subranges (we want to be
2047 * able to read any entry in those subranges with constant complexity).
2048 * In order to provide such iterators we resort to
2049 * std_cxx20::ranges::iota_view.
2053 * The bulk of the following piece of code is spent defining
2054 * the "worker" <code>on_subranges</code>: i.e. the operation applied at
2055 * each row of the sub-range. Given a fixed <code>row_index</code>
2056 * we want to visit every column/entry in such row. In order to execute
2057 * such columns-loops we use
2058 * <a href="http://www.cplusplus.com/reference/algorithm/for_each/">
2060 * from the standard library, where:
2061 * - <code>sparsity_pattern.begin(row_index)</code>
2062 * gives us an iterator starting at the first column of the row,
2063 * - <code>sparsity_pattern.end(row_index)</code> is an iterator pointing
2064 * at the last column of the row,
2065 * - the last argument required by `std::for_each` is the operation
2066 * applied at each nonzero entry (a lambda expression in this case)
2071 * We note that, parallel::apply_to_subranges() will operate on
2072 * disjoint sets of rows (the subranges) and our goal is to write into
2073 * these rows. Because of the simple nature of the operations we want
2074 * to carry out (computation and storage of normals, and normalization
2075 * of the @f$\mathbf{c}_{ij}@f$ of entries) threads cannot conflict
2076 * attempting to write the same entry (we do not need a scheduler).
2080 * TimerOutput::Scope scope(computing_timer,
2081 * "offline_data - compute |c_ij|, and n_ij");
2083 * const std_cxx20::ranges::iota_view<unsigned int, unsigned int> indices(
2084 * 0, n_locally_relevant);
2086 * const auto on_subranges =
2087 * [&](const auto index_begin, const auto index_end) {
2088 * for (const auto row_index :
2089 * std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
2090 * *index_begin, *index_end))
2094 * First column-loop: we compute and store the entries of the
2095 * matrix norm_matrix and write normalized entries into the
2096 * matrix nij_matrix:
2099 * std::for_each(sparsity_pattern.begin(row_index),
2100 * sparsity_pattern.end(row_index),
2101 * [&](const SparsityPatternIterators::Accessor &jt) {
2103 * gather_get_entry(cij_matrix, &jt);
2104 * const double norm = c_ij.norm();
2106 * set_entry(norm_matrix, &jt, norm);
2107 * for (unsigned int j = 0; j < dim; ++j)
2108 * set_entry(nij_matrix[j], &jt, c_ij[j] / norm);
2113 * parallel::apply_to_subranges(indices.begin(),
2120 * Finally, we normalize the vectors stored in
2121 * <code>OfflineData<dim>::BoundaryNormalMap</code>. This operation has
2122 * not been thread parallelized as it would neither illustrate any
2123 * important concept nor lead to any noticeable speed gain.
2126 * for (auto &it : boundary_normal_map)
2128 * auto &normal = std::get<0>(it.second);
2129 * normal /= (normal.norm() + std::numeric_limits<double>::epsilon());
2136 * At this point we are very much done with anything related to offline data.
2141 * <a name="step_69-EquationofstateandapproximateRiemannsolver"></a>
2142 * <h4>Equation of state and approximate Riemann solver</h4>
2146 * In this section we describe the implementation of the class members of
2147 * the <code>ProblemDescription</code> class. Most of the code here is
2167 *
template <
int dim>
2172 *
std::copy_n(&U[1], dim, &
result[0]);
2176 *
template <
int dim>
2180 *
const double &
rho =
U[0];
2182 *
const double &
E =
U[dim + 1];
2186 *
template <
int dim>
2193 *
template <
int dim>
2197 *
const double &
rho =
U[0];
2203 *
template <
int dim>
2207 *
const double &
rho =
U[0];
2210 *
const double &
E =
U[dim + 1];
2215 *
for (
unsigned int i = 0; i < dim; ++i)
2280 *
template <
int dim>
2364 *
const double factor = (
gamma + 1.0) / 2.0 / gamma;
2366 *
return u - a *
std::sqrt(1.0 + factor * tmp);
2391 *
const double factor = (
gamma + 1.0) / 2.0 / gamma;
2393 *
return u + a *
std::sqrt(1.0 + factor * tmp);
2511 *
{
"rho",
"m",
"E"}};
2515 *
{
"rho",
"m_1",
"m_2",
"E"}};
2519 *
{
"rho",
"m_1",
"m_2",
"m_3",
"E"}};
2524 * <a name=
"step_69-Initialvalues"></a>
2550 *
template <
int dim>
2560 *
add_parameter(
"initial direction",
2562 *
"Initial direction of the uniform flow field");
2567 *
add_parameter(
"initial 1d state",
2569 *
"Initial 1d state (rho, u, p) of the uniform flow field");
2582 * direction
is not the zero vector.
2597 *
template <
int dim>
2602 *
"Initial shock front direction is set to the zero vector."));
2626 *
for (
unsigned int i = 0; i < dim; ++i)
2629 *
state[dim + 1] = p / (
gamma - 1.) + 0.5 *
rho *
u *
u;
2638 * <a name=
"step_69-TheForwardEulerstep"></a>
2650 *
template <
int dim>
2658 *
, mpi_communicator(mpi_communicator)
2664 *
add_parameter(
"cfl update",
2666 *
"Relative CFL constant used for update");
2680 *
template <
int dim>
2681 *
void TimeStepping<dim>::prepare()
2684 *
"time_stepping - prepare scratch space");
2706 *
template <
int dim>
2707 *
double TimeStepping<dim>::make_one_step(vector_type &U,
const double t)
2717 *
const auto &sparsity =
offline_data->sparsity_pattern;
2780 *
"time_stepping - 1 compute d_ij");
2784 *
for (
const auto i :
2797 *
for (
auto jt = sparsity.begin(i);
jt != sparsity.end(i); ++
jt)
2799 *
const auto j =
jt->column();
2876 *
href=
"http://www.cplusplus.com/reference/atomic/atomic/"><
code>std::atomic<double></code></a>.
2888 *
std::atomic<double>
tau_max{std::numeric_limits<double>::infinity()};
2892 *
"time_stepping - 2 compute d_ii, and tau_max");
2908 *
for (
const auto i :
2912 *
double
d_sum = 0.;
2914 *
for (
auto jt = sparsity.begin(i);
jt != sparsity.end(i); ++
jt)
2916 *
const auto j =
jt->column();
2948 *
href=
"http://www.cplusplus.com/reference/atomic/atomic/"><
code>std::atomic<double></
code></a>
2985 *
"I'm sorry, Dave. I'm afraid I can't do that. - We crashed."));
3022 *
"time_stepping - 3 perform update");
3026 *
for (
const auto i :
3038 *
for (
auto jt = sparsity.begin(i);
jt != sparsity.end(i); ++
jt)
3040 *
const auto j =
jt->column();
3093 *
"time_stepping - 4 fix boundary states");
3107 *
const auto &normal = std::get<0>(
it.second);
3108 *
const auto &
id = std::get<1>(
it.second);
3109 *
const auto &position = std::get<2>(
it.second);
3122 *
m -= (m * normal) * normal;
3123 *
for (
unsigned int k = 0;
k < dim; ++
k)
3124 *
U_i[
k + 1] = m[
k];
3133 *
else if (
id == Boundaries::dirichlet)
3154 *
it.update_ghost_values();
3164 * <a name=
"step_69-Schlierenpostprocessing"></a>
3186 *
template <
int dim>
3193 *
, mpi_communicator(mpi_communicator)
3198 *
add_parameter(
"schlieren beta",
3200 *
"Beta factor used in Schlieren-type postprocessor");
3203 *
add_parameter(
"schlieren index",
3205 *
"Use the corresponding component of the state vector for the "
3206 *
"schlieren plot");
3218 *
template <
int dim>
3222 *
"schlieren_postprocessor - prepare scratch space");
3248 * \ \ \ \ \ \
mathbf{(*)} \f]
3254 * positive function
such as
3319 *
template <
int dim>
3323 *
computing_timer,
"schlieren_postprocessor - compute schlieren plot");
3325 *
const auto &sparsity =
offline_data->sparsity_pattern;
3331 *
const auto indices =
3341 *
std::atomic<double>
r_i_max{0.};
3342 *
std::atomic<double>
r_i_min{std::numeric_limits<double>::infinity()};
3356 *
for (
const auto i :
3363 *
for (
auto jt = sparsity.begin(i);
jt != sparsity.end(i); ++
jt)
3365 *
const auto j =
jt->column();
3389 *
const auto &normal = std::get<0>(
bnm_it->second);
3390 *
const auto &
id = std::get<1>(
bnm_it->second);
3393 *
r_i -= 1. * (
r_i * normal) * normal;
3466 *
for (
const auto i :
3494 * <a name=
"step_69-Themainloop"></a>
3517 *
template <
int dim>
3520 *
, mpi_communicator(mpi_communicator)
3530 *
"C - OfflineData")
3536 *
"E - TimeStepping")
3540 *
"F - SchlierenPostprocessor")
3542 *
base_name =
"test";
3543 *
add_parameter(
"basename", base_name,
"Base name for all output files");
3546 *
add_parameter(
"final time",
t_final,
"Final time");
3549 *
add_parameter(
"output granularity",
3551 *
"time interval for output");
3554 *
add_parameter(
"asynchronous writeback",
3556 *
"Write out solution in a background thread performing IO");
3559 *
add_parameter(
"resume",
resume,
"Resume an interrupted computation.");
3575 *
const std::string &
header,
3589 *
pcout << std::endl;
3590 *
pcout <<
" ####################################################" << std::endl;
3591 *
pcout <<
" ######### #########" << std::endl;
3594 *
pcout <<
" ######### #########" << std::endl;
3595 *
pcout <<
" ####################################################" << std::endl;
3596 *
pcout << std::endl;
3611 *
template <
int dim>
3630 *
pcout <<
"Reading parameters and allocating objects... " << std::flush;
3633 *
pcout <<
"done" << std::endl;
3652 *
discretization.triangulation.load(base_name +
"-checkpoint.mesh");
3656 *
pcout <<
"Number of active cells: "
3664 *
pcout <<
"Number of degrees of freedom: "
3685 *
for (
auto &
it :
U)
3691 * <a name=
"step_69-Resume"></a>
3710 * distributed::Triangulation::load() /
3711 * distributed::Triangulation::save()
mechanism to read in
the state
3729 *
std::vector<LinearAlgebra::distributed::Vector<double> *> vectors;
3730 *
std::transform(
U.begin(),
3732 *
std::back_inserter(vectors),
3733 *
[](
auto &
it) { return ⁢ });
3736 *
for (
auto &
it :
U)
3737 *
it.update_ghost_values();
3739 *
std::ifstream file(base_name +
"-checkpoint.metadata",
3740 *
std::ios::binary);
3742 *
boost::archive::binary_iarchive
ia(file);
3775 *
std::ostringstream
head;
3780 *
<< std::fixed << std::setprecision(1) << t /
t_final * 100
3782 *
secondary <<
"at time t = " << std::setprecision(8) << std::fixed << t;
3845 *
template <
int dim>
3849 *
pcout <<
"MainLoop<dim>::interpolate_initial_values(t = " << t <<
')'
3852 *
"main_loop - setup scratch space");
3856 *
for (
auto &
it :
U)
3877 * return initial_values.initial_state(x, t)[i];
3881 *
for (
auto &
it :
U)
3882 *
it.update_ghost_values();
3890 * <a name=
"step_69-Outputandcheckpointing"></a>
3903 *
template <
int dim>
3905 *
const std::string &name,
3907 *
const unsigned int cycle)
3915 *
std::vector<const LinearAlgebra::distributed::Vector<double> *> vectors;
3916 *
std::transform(
U.begin(),
3918 *
std::back_inserter(vectors),
3919 *
[](
auto &
it) { return ⁢ });
3927 *
std::ofstream file(name +
"-checkpoint.metadata", std::ios::binary);
3928 *
boost::archive::binary_oarchive
oa(file);
3952 *
template <
int dim>
3954 *
const std::string &name,
3956 *
const unsigned int cycle)
3958 *
pcout <<
"MainLoop<dim>::output(t = " << t <<
')' << std::endl;
3967 *
href=
"https://en.cppreference.com/w/cpp/thread/async"><
code>std::async()</
code></a>
3969 *
href=
"https://en.cppreference.com/w/cpp/thread/future"><
code>std::future</
code></a>
4011 *
std::unique_ptr<DataOut<dim>> data_out = std::make_unique<DataOut<dim>>();
4012 *
data_out->attach_dof_handler(
offline_data.dof_handler);
4019 *
"schlieren_plot");
4027 *
href=
"https://en.cppreference.com/w/cpp/language/lambda">
capture</a>
4052 *
[
data_out_copy = std::move(data_out),
this, name, t, cycle]() {
4058 *
"", name +
"-solution", cycle, mpi_communicator, 6);
4066 *
href=
"https://en.cppreference.com/w/cpp/thread/async"><
code>std::async</
code></a>
4068 *
href=
"https://en.cppreference.com/w/cpp/thread/future"><
code>std::future</
code></a>
4100 *
constexpr int dim = 2;
4102 *
using namespace dealii;
4103 *
using namespace Step69;
4112 *
catch (std::exception &exc)
4114 *
std::cerr << std::endl
4116 *
<<
"----------------------------------------------------"
4118 *
std::cerr <<
"Exception on processing: " << std::endl
4119 *
<< exc.what() << std::endl
4120 *
<<
"Aborting!" << std::endl
4121 *
<<
"----------------------------------------------------"
4127 *
std::cerr << std::endl
4129 *
<<
"----------------------------------------------------"
4131 *
std::cerr <<
"Unknown exception!" << std::endl
4132 *
<<
"Aborting!" << std::endl
4133 *
<<
"----------------------------------------------------"
4148 ####################################################
4152 ####################################################
4156 ####################################################
4160 ####################################################
4164 ####################################################
4166 ######### set
up time step #########
4168 ####################################################
4170 ####################################################
4175 ####################################################
4180 ####################################################
4185 ####################################################
4187 ####################################################
4189 ######### Cycle 000001 (0.0%) #########
4190 ######### at time t = 0.00000000 #########
4192 ####################################################
4196 ####################################################
4198 ######### Cycle 007553 (100.0%) #########
4199 ######### at time t = 3.99984036 #########
4201 ####################################################
4205+------------------------------------------------------------------------+------------+------------+
4209+------------------------------------------------------------+-----------+------------+------------+
4213|
offline_data - create sparsity pattern
and set
up matrices | 1 | 0.0224s | 0% |
4225+------------------------------------------------------------+-----------+------------+------------+
4235<
img src=
"https://www.dealii.org/images/steps/developer/step-69.coarse.gif" alt=
"" height=
"300">
4243<
img src=
"https://www.dealii.org/images/steps/developer/step-69.2nd-order.t400.jpg" alt=
"" height=
"300">
4253 ####################################################
4255 ######### Cycle 070216 (100.0%) #########
4256 ######### at time t = 3.99999231 #########
4258 ####################################################
4264+------------------------------------------------------------------------+------------+------------+
4268+------------------------------------------------------------+-----------+------------+------------+
4284+------------------------------------------------------------+-----------+------------+------------+
4289<
img src=
"https://www.dealii.org/images/steps/developer/step-69.fine.gif" alt=
"" height=
"300">
4291That's substantially better, although of course at the price of having run
4292the code for roughly 2 hours on 16 cores.
4296<a name="step-69-extensions"></a>
4297<a name="step_69-Possibilitiesforextensions"></a><h3>Possibilities for extensions</h3>
4300The program showcased here is really only first-order accurate, as
4301discussed above. The pictures above illustrate how much diffusion that
4302introduces and how far the solution is from one that actually resolves
4303the features we care about.
4305This can be fixed, but it would exceed what a *tutorial* is about.
4306Nevertheless, it is worth showing what one can achieve by adding a
4307second-order scheme. For example, here is a video computed with <a
4308href=https://conservation-laws.org/>the following research code</a>
4309that shows (with a different color scheme) a 2d simulation that corresponds
4310to the cases shown above:
4314 <iframe width="560" height="315" src="https://www.youtube.com/embed/xIwJZlsXpZ4"
4316 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
4317 allowfullscreen></iframe>
4321This simulation was done with 38 million degrees of freedom
4322(continuous @f$Q_1@f$ finite elements) per component of the solution
4323vector. The exquisite detail of the solution is remarkable for these
4324kinds of simulations, including in the sub-sonic region behind the
4327One can also with relative ease further extend this to the 3d case:
4331 <iframe width="560" height="315" src="https://www.youtube.com/embed/vBCRAF_c8m8"
4333 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
4334 allowfullscreen></iframe>
4338Solving this becomes expensive, however: The simulation was done with
43391,817 million degrees of freedom (continuous @f$Q_1@f$ finite elements)
4340per component (for a total of 9.09 billion spatial degrees of freedom)
4341and ran on 30,720 MPI ranks. The code achieved an average throughput of
4342969M grid points per second (0.04M gridpoints per second per CPU). The
4343front and back wall show a "Schlieren plot": the magnitude of the
4344gradient of the density on an exponential scale from white (low) to
4345black (high). All other cutplanes and the surface of the obstacle show
4346the magnitude of the vorticity on a white (low) - yellow (medium) -
4347red (high) scale. (The scales of the individual cutplanes have been
4348adjusted for a nicer visualization.)
4351<a name="step_69-PlainProg"></a>
4352<h1> The plain program</h1>
4353@include "step-69.cc"
virtual void build_patches(const unsigned int n_subdivisions=0)
static void initialize(const std::string &filename="", const std::string &output_filename="", const ParameterHandler::OutputStyle output_style_for_output_filename=ParameterHandler::Short, ParameterHandler &prm=ParameterAcceptor::prm, const ParameterHandler::OutputStyle output_style_for_filename=ParameterHandler::DefaultStyle)
boost::signals2::signal< void()> parse_parameters_call_back
void add_parameter(const std::string &entry, ParameterType ¶meter, const std::string &documentation="", ParameterHandler &prm_=prm, const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern())
Tensor< rank, dim, Number > sum(const Tensor< rank, dim, Number > &local, const MPI_Comm mpi_communicator)
numbers::NumberTraits< Number >::real_type norm() const
std::conditional_t< rank_==1, std::array< Number, dim >, std::array< Tensor< rank_ - 1, dim, Number >, dim > > values
constexpr numbers::NumberTraits< Number >::real_type norm_square() const
#define DEAL_II_ALWAYS_INLINE
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::cell_iterator cell_iterator
void loop(IteratorType begin, std_cxx20::type_identity_t< IteratorType > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, AssemblerType &assembler, const LoopControl &lctrl=LoopControl())
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
IteratorRange< BaseIterator > make_iterator_range(const BaseIterator &begin, const std_cxx20::type_identity_t< BaseIterator > &end)
std::vector< index_type > data
@ valid
Iterator points to a valid object.
@ matrix
Contents is actually a matrix.
@ symmetric
Matrix is symmetric.
@ diagonal
Matrix is diagonal.
@ general
No special properties.
constexpr types::blas_int one
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
T scatter(const MPI_Comm comm, const std::vector< T > &objects_to_send, const unsigned int root_process=0)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
void run(const std::vector< std::vector< Iterator > > &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
bool check(const ConstraintKinds kind_in, const unsigned int dim)
long double gamma(const unsigned int n)
void copy(const T *begin, const T *end, U *dest)
int(&) functions(const void *v1, const void *v2)
void assemble(const MeshWorker::DoFInfoBox< dim, DOFINFO > &dinfo, A *assembler)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
void apply_to_subranges(const tbb::blocked_range< Iterator > &range, const Function &f)
void apply_to_subranges(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, const Function &f, const unsigned int grainsize)
boost::integer_range< IncrementableType > iota_view
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
void swap(ObserverPointer< T, P > &t1, ObserverPointer< T, Q > &t2)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
DEAL_II_HOST constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
void advance(std::tuple< I1, I2 > &t, const unsigned int n)
void gather(VectorizedArray< Number, width > &out, const std::array< Number *, width > &ptrs, const unsigned int offset)