113 std::cout <<
"Postprocessor<dim, Number>::compute()" << std::endl;
116 copy_to_memory_space<dealii::MemorySpace::Host>(
119 const auto U_view = state_vector.
U.template view<problem_dimension>();
121 using VA = dealii::VectorizedArray<Number>;
123 const auto &affine_constraints = offline_data_->affine_constraints();
125 const auto sparsity_simd_view =
126 offline_data_->sparsity_pattern_simd().view();
127 const auto lumped_mass_matrix_view =
128 offline_data_->lumped_mass_matrix().template view<1>();
129 const auto cij_matrix_view = offline_data_->cij_matrix().view();
131 const unsigned int n_internal = offline_data_->n_locally_internal();
132 const unsigned int n_owned = offline_data_->n_locally_owned();
134 const unsigned int n_schlieren = schlieren_indices_.size();
135 Assert(n_schlieren == schlieren_quantities_.size(),
136 dealii::ExcInternalError());
137 const unsigned int n_vorticities = vorticity_indices_.size();
138 Assert(n_vorticities == vorticity_quantities_.size(),
139 dealii::ExcInternalError());
140 const unsigned int n_quantities = n_schlieren + n_vorticities;
141 Assert(n_quantities == quantities_.size(), dealii::ExcInternalError());
142 Assert(n_quantities == component_names_.size(), dealii::ExcInternalError());
148 const auto body = [&](
auto sentinel,
unsigned int i) {
149 using T =
decltype(sentinel);
150 const unsigned int stride_size = sparsity_simd_view.stride_of_row(i);
153 const unsigned int row_length = sparsity_simd_view.row_length(i);
157 std::vector<grad_type<T>> local_schlieren_values(n_schlieren);
158 std::vector<curl_type<T>> local_vorticity_values(n_vorticities);
160 for (
auto &it : local_schlieren_values)
162 for (
auto &it : local_vorticity_values)
165 const unsigned int *js = sparsity_simd_view.columns(i);
166 for (
unsigned int col_idx = 0; col_idx < row_length;
167 ++col_idx, js += stride_size) {
169 const auto U_j = U_view.template read_tensor<T>(js);
170 const auto view = hyperbolic_system_->template view<dim, T>();
171 const auto prim_j = view.to_primitive_state(U_j);
173 const auto c_ij = cij_matrix_view.template read_tensor<T>(i, col_idx);
176 for (
const auto &[is_primitive, index] : schlieren_indices_) {
177 local_schlieren_values[k++] -=
178 c_ij * (is_primitive ? prim_j[index] : U_j[index]);
182 for (
const auto &[is_primitive, index] : vorticity_indices_) {
184 for (
unsigned int d = 0; d < dim; ++d)
185 q_j[d] = (is_primitive ? prim_j[index + d] : U_j[index + d]);
187 if constexpr (dim == 2) {
188 local_vorticity_values[k++][0] -= cross_product_2d(c_ij) * q_j;
189 }
else if constexpr (dim == 3) {
190 local_vorticity_values[k++] -= cross_product_3d(c_ij, q_j);
196 const auto m_i = lumped_mass_matrix_view.template read_entry<T>(i);
199 for (
const auto &schlieren : local_schlieren_values) {
200 const auto value_i = schlieren.norm() / m_i;
201 write_entry<T>(quantities_[k++], value_i, i);
203 for (
const auto &vorticity : local_vorticity_values) {
204 auto value_i = (dim == 2 ? vorticity[0] / m_i : vorticity.norm() / m_i);
205 write_entry<T>(quantities_[k++], value_i, i);
209 cpu_simd_loop<Number>(
"", body, 0, n_internal, n_owned);
216 if (recompute_bounds_)
219 if (bounds_.size() != n_quantities) {
223 std::make_pair(Number(0.), std::numeric_limits<Number>::max()));
225 for (
unsigned int d = 0; d < n_quantities; ++d) {
226 auto &[q_max, q_min] = bounds_[d];
227 for (
unsigned int i = 0; i < n_owned; ++i) {
228 const auto q = quantities_[d].local_element(i);
229 q_max = std::max(q_max, std::abs(q));
230 q_min = std::min(q_min, std::abs(q));
232 q_max = dealii::Utilities::MPI::max(
233 q_max, mpi_ensemble_.ensemble_communicator());
234 q_min = dealii::Utilities::MPI::min(
235 q_min, mpi_ensemble_.ensemble_communicator());
236 Assert(q_max >= q_min, dealii::ExcInternalError());
245 constexpr Number eps = std::numeric_limits<Number>::epsilon();
246 constexpr Number floor = std::max(Number(1.0e-10), eps);
248 for (
unsigned int d = 0; d < n_quantities; ++d) {
249 auto &[q_max, q_min] = bounds_[d];
250 for (
unsigned int i = 0; i < n_owned; ++i) {
251 auto &q = quantities_[d].local_element(i);
253 const auto ratio = std::max(Number(0.), std::abs(q) - q_min - floor) /
254 std::max(q_max - q_min, eps);
256 const auto magnitude = Number(1.) - std::exp(-beta_ * ratio);
257 q = std::copysign(magnitude, q);
266 for (
auto &it : quantities_) {
267 affine_constraints.distribute(it);
268 it.update_ghost_values();