1504 *
cell->get_dof_indices(dof_indices);
1505 *
std::transform(dof_indices.begin(),
1506 *
dof_indices.
end(),
1507 *
dof_indices.
begin(),
1509 * return partitioner->global_to_local(index);
1514 *
for (
const auto dof : dof_indices)
1515 *
dsp.add_entries(dof, dof_indices.
begin(), dof_indices.
end());
1518 *
sparsity_pattern.copy_from(
dsp);
1554 *
template <
int dim>
1557 *
bool is_artificial;
1558 *
std::vector<types::global_dof_index> local_dof_indices;
1569 * <a
href=
"https://en.wikipedia.org/wiki/Syntactic_sugar">
syntactic
1591 *
template <
typename IteratorType>
1596 *
&matrix,
it->global_index());
1610 *
template <
typename IteratorType>
1617 *
it->global_index());
1636 *
template <std::
size_t k,
typename IteratorType>
1642 *
for (
unsigned int j = 0;
j <
k; ++
j)
1683 *
for (
unsigned int l = 0;
l <
k; ++
l)
1705 *
for (
unsigned int j = 0;
j <
k; ++
j)
1706 *
result[
j] = U[
j].local_element(i);
1728 *
const unsigned int i)
1730 *
static_assert(
k ==
k2,
1731 *
"The dimensions of the input arguments must agree");
1732 *
for (
unsigned int j = 0;
j <
k; ++
j)
1733 *
U[
j].local_element(i) = tensor[
j];
1748 *
detailed in
the @
ref threads
"Parallel computing with multiple processors"
1795 *
template <
int dim>
1805 *
unsigned int dofs_per_cell =
1830 *
"offline_data - assemble lumped mass matrix, and c_ij");
1836 *
copy.is_artificial = cell->is_artificial();
1837 *
if (
copy.is_artificial)
1840 *
copy.local_boundary_normal_map.clear();
1841 *
copy.cell_lumped_mass_matrix.reinit(dofs_per_cell, dofs_per_cell);
1845 *
const auto &fe_values = scratch.
reinit(cell);
1847 *
copy.local_dof_indices.resize(dofs_per_cell);
1848 *
cell->get_dof_indices(
copy.local_dof_indices);
1850 *
std::transform(
copy.local_dof_indices.begin(),
1851 *
copy.local_dof_indices.end(),
1852 *
copy.local_dof_indices.begin(),
1854 * return partitioner->global_to_local(index);
1865 *
const auto JxW = fe_values.JxW(
q_point);
1867 *
for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1870 *
fe_values.shape_value(
j,
q_point) * JxW;
1875 *
for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1877 *
const auto value = fe_values.shape_value(i,
q_point);
1878 *
for (
unsigned int d = 0;
d < dim; ++
d)
1892 *
for (
const auto f : cell->face_indices())
1895 *
const auto id = face->boundary_id();
1897 *
if (!face->at_boundary())
1900 *
const auto &fe_face_values = scratch.
reinit(cell, f);
1903 *
fe_face_values.get_quadrature().
size();
1905 *
for (
unsigned int j = 0;
j < dofs_per_cell; ++
j)
1925 *
normal += fe_face_values.normal_vector(
q) *
1926 *
fe_face_values.shape_value(
j,
q);
1929 *
const auto index =
copy.local_dof_indices[
j];
1933 *
if (cell->vertex_dof_index(v, 0) ==
1934 *
partitioner->local_to_global(
index))
1936 *
position = cell->vertex(v);
1941 *
std::get<1>(
copy.local_boundary_normal_map[index]);
1942 *
copy.local_boundary_normal_map[
index] =
1955 *
if (
copy.is_artificial)
1964 *
std::get<1>(
it.second));
1969 *
copy.cell_lumped_mass_matrix);
1971 *
for (
int k = 0;
k < dim; ++
k)
1979 *
dof_handler.
end(),
1991 *
That's not what we really want: we have to normalize its entries. In
1992 * addition, we have not filled the entries of the matrix
1993 * <code>norm_matrix</code> and the vectors stored in the map
1994 * <code>OfflineData<dim>::BoundaryNormalMap</code> are not normalized.
1998 * In principle, this is just offline data, it doesn't
make much sense
2014 *
again.
That's why this is the right time to introduce them.
2018 * We have the thread parallelization capability
2019 * parallel::apply_to_subranges() that is somehow more general than the
2020 * WorkStream framework. In particular, parallel::apply_to_subranges() can
2021 * be used for our node-loops. This functionality requires four input
2022 * arguments which we explain in detail (for the specific case of our
2023 * thread-parallel node loops):
2024 * - The iterator <code>indices.begin()</code> points to a row index.
2025 * - The iterator <code>indices.end()</code> points to a numerically higher
2027 * - The function <code>on_subranges(index_begin, index_end)</code>
2028 * (where <code>index_begin</code> and <code>index_end</code>
2029 * define a sub-range within the range spanned by
2030 * the begin and end iterators defined in the two previous bullets)
2031 * applies an operation to every iterator in such subrange. We may as
2032 * well call <code>on_subranges</code> the "worker".
2033 * - Grainsize: minimum number of iterators (in this case representing
2034 * rows) processed by each thread. We decided for a minimum of 4096
2039 * A minor caveat here is that the iterators <code>indices.begin()</code>
2040 * and <code>indices.end()</code> supplied to
2041 * parallel::apply_to_subranges() have to be random access iterators:
2042 * internally, parallel::apply_to_subranges() will break the range
2043 * defined by the <code>indices.begin()</code> and
2044 * <code>indices.end()</code> iterators into subranges (we want to be
2045 * able to read any entry in those subranges with constant complexity).
2046 * In order to provide such iterators we resort to
2047 * std_cxx20::ranges::iota_view.
2051 * The bulk of the following piece of code is spent defining
2052 * the "worker" <code>on_subranges</code>: i.e. the operation applied at
2053 * each row of the sub-range. Given a fixed <code>row_index</code>
2054 * we want to visit every column/entry in such row. In order to execute
2055 * such columns-loops we use
2056 * <a href="http://www.cplusplus.com/reference/algorithm/for_each/">
2058 * from the standard library, where:
2059 * - <code>sparsity_pattern.begin(row_index)</code>
2060 * gives us an iterator starting at the first column of the row,
2061 * - <code>sparsity_pattern.end(row_index)</code> is an iterator pointing
2062 * at the last column of the row,
2063 * - the last argument required by `std::for_each` is the operation
2064 * applied at each nonzero entry (a lambda expression in this case)
2069 * We note that, parallel::apply_to_subranges() will operate on
2070 * disjoint sets of rows (the subranges) and our goal is to write into
2071 * these rows. Because of the simple nature of the operations we want
2072 * to carry out (computation and storage of normals, and normalization
2073 * of the @f$\mathbf{c}_{ij}@f$ of entries) threads cannot conflict
2074 * attempting to write the same entry (we do not need a scheduler).
2078 * TimerOutput::Scope scope(computing_timer,
2079 * "offline_data - compute |c_ij|, and n_ij");
2081 * const std_cxx20::ranges::iota_view<unsigned int, unsigned int> indices(
2082 * 0, n_locally_relevant);
2084 * const auto on_subranges =
2085 * [&](const auto index_begin, const auto index_end) {
2086 * for (const auto row_index :
2087 * std_cxx20::ranges::iota_view<unsigned int, unsigned int>(
2088 * *index_begin, *index_end))
2092 * First column-loop: we compute and store the entries of the
2093 * matrix norm_matrix and write normalized entries into the
2094 * matrix nij_matrix:
2097 * std::for_each(sparsity_pattern.begin(row_index),
2098 * sparsity_pattern.end(row_index),
2099 * [&](const SparsityPatternIterators::Accessor &jt) {
2101 * gather_get_entry(cij_matrix, &jt);
2102 * const double norm = c_ij.norm();
2104 * set_entry(norm_matrix, &jt, norm);
2105 * for (unsigned int j = 0; j < dim; ++j)
2106 * set_entry(nij_matrix[j], &jt, c_ij[j] / norm);
2111 * parallel::apply_to_subranges(indices.begin(),
2118 * Finally, we normalize the vectors stored in
2119 * <code>OfflineData<dim>::BoundaryNormalMap</code>. This operation has
2120 * not been thread parallelized as it would neither illustrate any
2121 * important concept nor lead to any noticeable speed gain.
2124 * for (auto &it : boundary_normal_map)
2126 * auto &normal = std::get<0>(it.second);
2127 * normal /= (normal.norm() + std::numeric_limits<double>::epsilon());
2134 * At this point we are very much done with anything related to offline data.
2139 * <a name="EquationofstateandapproximateRiemannsolver"></a>
2140 * <h4>Equation of state and approximate Riemann solver</h4>
2144 * In this section we describe the implementation of the class members of
2145 * the <code>ProblemDescription</code> class. Most of the code here is
2165 *
template <
int dim>
2170 *
std::copy_n(&U[1], dim, &
result[0]);
2174 *
template <
int dim>
2178 *
const double &
rho = U[0];
2180 *
const double &
E = U[dim + 1];
2181 *
return E - 0.5 * m.norm_square() /
rho;
2184 *
template <
int dim>
2191 *
template <
int dim>
2195 *
const double &
rho = U[0];
2201 *
template <
int dim>
2205 *
const double &
rho = U[0];
2208 *
const double &
E = U[dim + 1];
2213 *
for (
unsigned int i = 0; i < dim; ++i)
2278 *
template <
int dim>
2362 *
const double factor = (
gamma + 1.0) / 2.0 / gamma;
2364 *
return u - a *
std::sqrt(1.0 + factor * tmp);
2389 *
const double factor = (
gamma + 1.0) / 2.0 / gamma;
2391 *
return u + a *
std::sqrt(1.0 + factor * tmp);
2509 *
{
"rho",
"m",
"E"}};
2513 *
{
"rho",
"m_1",
"m_2",
"E"}};
2517 *
{
"rho",
"m_1",
"m_2",
"m_3",
"E"}};
2522 * <a name=
"Initialvalues"></a>
2548 *
template <
int dim>
2558 *
add_parameter(
"initial direction",
2560 *
"Initial direction of the uniform flow field");
2565 *
add_parameter(
"initial 1d state",
2567 *
"Initial 1d state (rho, u, p) of the uniform flow field");
2580 * direction
is not the zero vector.
2595 *
template <
int dim>
2600 *
"Initial shock front direction is set to the zero vector."));
2624 *
for (
unsigned int i = 0; i < dim; ++i)
2627 *
state[dim + 1] = p / (
gamma - 1.) + 0.5 *
rho *
u *
u;
2636 * <a name=
"TheForwardEulerstep"></a>
2648 *
template <
int dim>
2656 *
, mpi_communicator(mpi_communicator)
2662 *
add_parameter(
"cfl update",
2664 *
"Relative CFL constant used for update");
2678 *
template <
int dim>
2679 *
void TimeStepping<dim>::prepare()
2682 *
"time_stepping - prepare scratch space");
2704 *
template <
int dim>
2705 *
double TimeStepping<dim>::make_one_step(vector_type &U,
const double t)
2715 *
const auto &sparsity =
offline_data->sparsity_pattern;
2778 *
"time_stepping - 1 compute d_ij");
2782 *
for (
const auto i :
2797 *
const auto j =
jt->column();
2874 *
href=
"http://www.cplusplus.com/reference/atomic/atomic/"><
code>std::atomic<double></code></a>.
2886 *
std::atomic<double>
tau_max{std::numeric_limits<double>::infinity()};
2890 *
"time_stepping - 2 compute d_ii, and tau_max");
2906 *
for (
const auto i :
2910 *
double
d_sum = 0.;
2914 *
const auto j =
jt->column();
2946 *
href=
"http://www.cplusplus.com/reference/atomic/atomic/"><
code>std::atomic<double></
code></a>
2983 *
"I'm sorry, Dave. I'm afraid I can't do that. - We crashed."));
3020 *
"time_stepping - 3 perform update");
3024 *
for (
const auto i :
3038 *
const auto j =
jt->column();
3091 *
"time_stepping - 4 fix boundary states");
3105 *
const auto &normal = std::get<0>(
it.second);
3106 *
const auto &
id = std::get<1>(
it.second);
3107 *
const auto &position = std::get<2>(
it.second);
3120 *
m -= (m * normal) * normal;
3121 *
for (
unsigned int k = 0;
k < dim; ++
k)
3122 *
U_i[
k + 1] = m[
k];
3131 *
else if (
id == Boundaries::dirichlet)
3152 *
it.update_ghost_values();
3162 * <a name=
"Schlierenpostprocessing"></a>
3184 *
template <
int dim>
3191 *
, mpi_communicator(mpi_communicator)
3196 *
add_parameter(
"schlieren beta",
3198 *
"Beta factor used in Schlieren-type postprocessor");
3201 *
add_parameter(
"schlieren index",
3203 *
"Use the corresponding component of the state vector for the "
3204 *
"schlieren plot");
3216 *
template <
int dim>
3220 *
"schlieren_postprocessor - prepare scratch space");
3246 * \ \ \ \ \ \
mathbf{(*)} \f]
3252 * positive function
such as
3317 *
template <
int dim>
3321 *
computing_timer,
"schlieren_postprocessor - compute schlieren plot");
3323 *
const auto &sparsity =
offline_data->sparsity_pattern;
3329 *
const auto indices =
3339 *
std::atomic<double>
r_i_max{0.};
3340 *
std::atomic<double>
r_i_min{std::numeric_limits<double>::infinity()};
3354 *
for (
const auto i :
3363 *
const auto j =
jt->column();
3387 *
const auto &normal = std::get<0>(
bnm_it->second);
3388 *
const auto &
id = std::get<1>(
bnm_it->second);
3391 *
r_i -= 1. * (
r_i * normal) * normal;
3405 *
r[i] =
r_i.norm() /
m_i;
3464 *
for (
const auto i :
3492 * <a name=
"Themainloop"></a>
3515 *
template <
int dim>
3518 *
, mpi_communicator(mpi_communicator)
3528 *
"C - OfflineData")
3534 *
"E - TimeStepping")
3538 *
"F - SchlierenPostprocessor")
3540 *
base_name =
"test";
3541 *
add_parameter(
"basename", base_name,
"Base name for all output files");
3544 *
add_parameter(
"final time",
t_final,
"Final time");
3547 *
add_parameter(
"output granularity",
3549 *
"time interval for output");
3552 *
add_parameter(
"asynchronous writeback",
3554 *
"Write out solution in a background thread performing IO");
3557 *
add_parameter(
"resume",
resume,
"Resume an interrupted computation.");
3573 *
const std::string &
header,
3587 *
pcout << std::endl;
3588 *
pcout <<
" ####################################################" << std::endl;
3589 *
pcout <<
" ######### #########" << std::endl;
3592 *
pcout <<
" ######### #########" << std::endl;
3593 *
pcout <<
" ####################################################" << std::endl;
3594 *
pcout << std::endl;
3609 *
template <
int dim>
3628 *
pcout <<
"Reading parameters and allocating objects... " << std::flush;
3631 *
pcout <<
"done" << std::endl;
3650 *
discretization.triangulation.load(base_name +
"-checkpoint.mesh");
3654 *
pcout <<
"Number of active cells: "
3662 *
pcout <<
"Number of degrees of freedom: "
3683 *
for (
auto &
it : U)
3689 * <a name=
"Resume"></a>
3708 * distributed::Triangulation::load() /
3709 * distributed::Triangulation::save()
mechanism to read in
the state
3727 *
std::vector<LinearAlgebra::distributed::Vector<double> *> vectors;
3728 *
std::transform(U.
begin(),
3730 *
std::back_inserter(vectors),
3731 *
[](
auto &
it) { return ⁢ });
3734 *
for (
auto &
it : U)
3735 *
it.update_ghost_values();
3737 *
std::ifstream file(base_name +
"-checkpoint.metadata",
3738 *
std::ios::binary);
3740 *
boost::archive::binary_iarchive
ia(file);
3773 *
std::ostringstream
head;
3778 *
<< std::fixed << std::setprecision(1) << t /
t_final * 100
3780 *
secondary <<
"at time t = " << std::setprecision(8) << std::fixed << t;
3843 *
template <
int dim>
3847 *
pcout <<
"MainLoop<dim>::interpolate_initial_values(t = " << t <<
')'
3850 *
"main_loop - setup scratch space");
3854 *
for (
auto &
it : U)
3875 * return initial_values.initial_state(x, t)[i];
3879 *
for (
auto &
it : U)
3880 *
it.update_ghost_values();
3888 * <a name=
"Outputandcheckpointing"></a>
3901 *
template <
int dim>
3903 *
const std::string &name,
3905 *
const unsigned int cycle)
3913 *
std::vector<const LinearAlgebra::distributed::Vector<double> *> vectors;
3914 *
std::transform(U.
begin(),
3916 *
std::back_inserter(vectors),
3917 *
[](
auto &
it) { return ⁢ });
3925 *
std::ofstream file(name +
"-checkpoint.metadata", std::ios::binary);
3926 *
boost::archive::binary_oarchive
oa(file);
3950 *
template <
int dim>
3952 *
const std::string & name,
3954 *
const unsigned int cycle)
3956 *
pcout <<
"MainLoop<dim>::output(t = " << t <<
')' << std::endl;
3965 *
href=
"https://en.cppreference.com/w/cpp/thread/async"><
code>std::async()</
code></a>
3967 *
href=
"https://en.cppreference.com/w/cpp/thread/future"><
code>std::future</
code></a>
4009 *
std::unique_ptr<DataOut<dim>> data_out = std::make_unique<DataOut<dim>>();
4010 *
data_out->attach_dof_handler(
offline_data.dof_handler);
4017 *
"schlieren_plot");
4025 *
href=
"https://en.cppreference.com/w/cpp/language/lambda">
capture</a>
4050 *
[
data_out_copy = std::move(data_out),
this, name, t, cycle]() {
4056 *
"", name +
"-solution", cycle, mpi_communicator, 6);
4064 *
href=
"https://en.cppreference.com/w/cpp/thread/async"><
code>std::async</
code></a>
4066 *
href=
"https://en.cppreference.com/w/cpp/thread/future"><
code>std::future</
code></a>
4098 *
constexpr int dim = 2;
4100 *
using namespace dealii;
4101 *
using namespace Step69;
4110 *
catch (std::exception &exc)
4112 *
std::cerr << std::endl
4114 *
<<
"----------------------------------------------------"
4116 *
std::cerr <<
"Exception on processing: " << std::endl
4117 *
<< exc.what() << std::endl
4118 *
<<
"Aborting!" << std::endl
4119 *
<<
"----------------------------------------------------"
4125 *
std::cerr << std::endl
4127 *
<<
"----------------------------------------------------"
4129 *
std::cerr <<
"Unknown exception!" << std::endl
4130 *
<<
"Aborting!" << std::endl
4131 *
<<
"----------------------------------------------------"
4137<a name=
"Results"></a>
4147 ####################################################
4151 ####################################################
4155 ####################################################
4157 ######### compute
offline data #########
4159 ####################################################
4163 ####################################################
4165 #########
set up time step #########
4167 ####################################################
4169 ####################################################
4174 ####################################################
4179 ####################################################
4184 ####################################################
4186 ####################################################
4188 ######### Cycle 000001 (0.0%) #########
4189 ######### at time t = 0.00000000 #########
4191 ####################################################
4195 ####################################################
4197 ######### Cycle 007553 (100.0%) #########
4198 ######### at time t = 3.99984036 #########
4200 ####################################################
4204+------------------------------------------------------------------------+------------+------------+
4208+------------------------------------------------------------+-----------+------------+------------+
4224+------------------------------------------------------------+-----------+------------+------------+
4234<
img src=
"https://www.dealii.org/images/steps/developer/step-69.coarse.gif" alt=
"" height=
"300">
4242<
img src=
"https://www.dealii.org/images/steps/developer/step-69.2nd-order.t400.jpg" alt=
"" height=
"300">
4252 ####################################################
4254 ######### Cycle 070216 (100.0%) #########
4255 ######### at time t = 3.99999231 #########
4257 ####################################################
4263+------------------------------------------------------------------------+------------+------------+
4267+------------------------------------------------------------+-----------+------------+------------+
4283+------------------------------------------------------------+-----------+------------+------------+
4288<
img src=
"https://www.dealii.org/images/steps/developer/step-69.fine.gif" alt=
"" height=
"300">
4290That's substantially better, although of course at the price of having run
4291the code for roughly 2 hours on 16 cores.
4295<a name="extensions"></a>
4296<a name="Possibilitiesforextensions"></a><h3>Possibilities for extensions</h3>
4299The program showcased here is really only first-order accurate, as
4300discussed above. The pictures above illustrate how much diffusion that
4301introduces and how far the solution is from one that actually resolves
4302the features we care about.
4304This can be fixed, but it would exceed what a *tutorial* is about.
4305Nevertheless, it is worth showing what one can achieve by adding a
4306second-order scheme. For example, here is a video computed with <a
4307href=https://conservation-laws.org/>the following research code</a>
4308that shows (with a different color scheme) a 2d simulation that corresponds
4309to the cases shown above:
4313 <iframe width="560" height="315" src="https://www.youtube.com/embed/xIwJZlsXpZ4"
4315 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
4316 allowfullscreen></iframe>
4320This simulation was done with 38 million degrees of freedom
4321(continuous @f$Q_1@f$ finite elements) per component of the solution
4322vector. The exquisite detail of the solution is remarkable for these
4323kinds of simulations, including in the sub-sonic region behind the
4326One can also with relative ease further extend this to the 3d case:
4330 <iframe width="560" height="315" src="https://www.youtube.com/embed/vBCRAF_c8m8"
4332 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
4333 allowfullscreen></iframe>
4337Solving this becomes expensive, however: The simulation was done with
43381,817 million degrees of freedom (continuous @f$Q_1@f$ finite elements)
4339per component (for a total of 9.09 billion spatial degrees of freedom)
4340and ran on 30,720 MPI ranks. The code achieved an average throughput of
4341969M grid points per second (0.04M gridpoints per second per CPU). The
4342front and back wall show a "Schlieren plot": the magnitude of the
4343gradient of the density on an exponential scale from white (low) to
4344black (high). All other cutplanes and the surface of the obstacle show
4345the magnitude of the vorticity on a white (low) - yellow (medium) -
4346red (high) scale. (The scales of the individual cutplanes have been
4347adjusted for a nicer visualization.)
4350<a name="PlainProg"></a>
4351<h1> The plain program</h1>
4352@include "step-69.cc"
value_type * data() const noexcept
void reinit(value_type *starting_element, const std::size_t n_elements)
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())
#define DEAL_II_ALWAYS_INLINE
__global__ void set(Number *val, const Number s, const size_type N)
#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(ITERATOR begin, std_cxx20::type_identity_t< ITERATOR > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &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)
@ 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.
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
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)
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)
void call(const std::function< RT()> &function, internal::return_value< RT > &ret_val)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
T sum(const T &t, const MPI_Comm mpi_communicator)
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 > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
void swap(SmartPointer< T, P > &t1, SmartPointer< T, Q > &t2)
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)