113 std::cout <<
"Postprocessor<dim, Number>::compute()" << std::endl;
119 const auto &[U, precomputed, parabolic] = state_vector;
120 U.template copy_to_memory_space<dealii::MemorySpace::Host>();
123 const auto U_view = std::get<0>(state_vector).view();
125 using VA = dealii::VectorizedArray<Number>;
127 const auto &affine_constraints = offline_data_->affine_constraints();
129 const auto sparsity_simd_view =
130 offline_data_->sparsity_pattern_simd().view();
131 const auto lumped_mass_matrix_view =
132 offline_data_->lumped_mass_matrix().view();
133 const auto cij_matrix_view = offline_data_->cij_matrix().view();
135 const unsigned int n_internal = offline_data_->n_locally_internal();
136 const unsigned int n_owned = offline_data_->n_locally_owned();
138 const unsigned int n_schlieren = schlieren_indices_.size();
139 Assert(n_schlieren == schlieren_quantities_.size(),
140 dealii::ExcInternalError());
141 const unsigned int n_vorticities = vorticity_indices_.size();
142 Assert(n_vorticities == vorticity_quantities_.size(),
143 dealii::ExcInternalError());
144 const unsigned int n_quantities = n_schlieren + n_vorticities;
145 Assert(n_quantities == quantities_.size(), dealii::ExcInternalError());
146 Assert(n_quantities == component_names_.size(), dealii::ExcInternalError());
152 const auto body = [&](
auto sentinel,
unsigned int i) {
153 using T =
decltype(sentinel);
154 constexpr unsigned int stride_size = get_stride_size<T>;
157 const unsigned int row_length = sparsity_simd_view.row_length(i);
161 std::vector<grad_type<T>> local_schlieren_values(n_schlieren);
162 std::vector<curl_type<T>> local_vorticity_values(n_vorticities);
164 for (
auto &it : local_schlieren_values)
166 for (
auto &it : local_vorticity_values)
169 const unsigned int *js = sparsity_simd_view.columns(i);
170 for (
unsigned int col_idx = 0; col_idx < row_length;
171 ++col_idx, js += stride_size) {
173 const auto U_j = U_view.template read_tensor<T>(js);
174 const auto view = hyperbolic_system_->template view<dim, T>();
175 const auto prim_j = view.to_primitive_state(U_j);
177 const auto c_ij = cij_matrix_view.template read_tensor<T>(i, col_idx);
180 for (
const auto &[is_primitive, index] : schlieren_indices_) {
181 local_schlieren_values[k++] -=
182 c_ij * (is_primitive ? prim_j[index] : U_j[index]);
186 for (
const auto &[is_primitive, index] : vorticity_indices_) {
188 for (
unsigned int d = 0; d < dim; ++d)
189 q_j[d] = (is_primitive ? prim_j[index + d] : U_j[index + d]);
191 if constexpr (dim == 2) {
192 local_vorticity_values[k++][0] -= cross_product_2d(c_ij) * q_j;
193 }
else if constexpr (dim == 3) {
194 local_vorticity_values[k++] -= cross_product_3d(c_ij, q_j);
200 const auto m_i = lumped_mass_matrix_view.template read_entry<T>(i);
203 for (
const auto &schlieren : local_schlieren_values) {
204 const auto value_i = schlieren.norm() / m_i;
205 write_entry<T>(quantities_[k++], value_i, i);
207 for (
const auto &vorticity : local_vorticity_values) {
208 auto value_i = (dim == 2 ? vorticity[0] / m_i : vorticity.norm() / m_i);
209 write_entry<T>(quantities_[k++], value_i, i);
213 cpu_simd_loop<Number>(
"", body, 0, n_internal, n_owned);
220 if (recompute_bounds_)
223 if (bounds_.size() != n_quantities) {
227 std::make_pair(Number(0.), std::numeric_limits<Number>::max()));
229 for (
unsigned int d = 0; d < n_quantities; ++d) {
230 auto &[q_max, q_min] = bounds_[d];
231 for (
unsigned int i = 0; i < n_owned; ++i) {
232 const auto q = quantities_[d].local_element(i);
233 q_max = std::max(q_max, std::abs(q));
234 q_min = std::min(q_min, std::abs(q));
236 q_max = dealii::Utilities::MPI::max(
237 q_max, mpi_ensemble_.ensemble_communicator());
238 q_min = dealii::Utilities::MPI::min(
239 q_min, mpi_ensemble_.ensemble_communicator());
240 Assert(q_max >= q_min, dealii::ExcInternalError());
249 constexpr Number eps = std::numeric_limits<Number>::epsilon();
250 constexpr Number floor = std::max(Number(1.0e-10), eps);
252 for (
unsigned int d = 0; d < n_quantities; ++d) {
253 auto &[q_max, q_min] = bounds_[d];
254 for (
unsigned int i = 0; i < n_owned; ++i) {
255 auto &q = quantities_[d].local_element(i);
257 const auto ratio = std::max(Number(0.), std::abs(q) - q_min - floor) /
258 std::max(q_max - q_min, eps);
260 const auto magnitude = Number(1.) - std::exp(-beta_ * ratio);
261 q = std::copysign(magnitude, q);
270 for (
auto &it : quantities_) {
271 affine_constraints.distribute(it);
272 it.update_ghost_values();