Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <iomanip> 7 : #include <sstream> 8 : #include <string> 9 : 10 : #include "DataStructures/DataBox/DataBox.hpp" 11 : #include "DataStructures/DataBox/PrefixHelpers.hpp" 12 : #include "DataStructures/DataBox/Prefixes.hpp" 13 : #include "Evolution/DiscontinuousGalerkin/InboxTags.hpp" 14 : #include "Evolution/DiscontinuousGalerkin/MortarTags.hpp" 15 : #include "Parallel/GlobalCache.hpp" 16 : #include "Parallel/OutputInbox.hpp" 17 : #include "Parallel/Printf/Printf.hpp" 18 : #include "Time/Tags/Time.hpp" 19 : #include "Time/Tags/TimeStep.hpp" 20 : #include "Time/Tags/TimeStepId.hpp" 21 : #include "Utilities/TaggedTuple.hpp" 22 : 23 : /*! 24 : * \brief Namespace for actions related to debugging deadlocks in communication. 25 : * 26 : * \details These actions will typically be run in the 27 : * `run_deadlock_analysis_simple_actions` function in the metavariables (if it 28 : * exists). 29 : */ 30 1 : namespace deadlock { 31 : /*! 32 : * \brief Simple action that will print a variety of information on evolution DG 33 : * elements 34 : * 35 : * \details This will print the contents of the following inbox or DataBox tags: 36 : * 37 : * - `evolution::dg::Tags::BoundaryCorrectionAndGhostCellsInbox<3>` 38 : * - `evolution::dg::Tags::MortarNextTemporalId<3>` 39 : * - `evolution::dg::Tags::MortarDataHistory` (for LTS only) 40 : * - `evolution::dg::Tags::MortarData<3>` (for GTS only) 41 : * 42 : * Inbox tags are printed using the `Parallel::output_inbox` function. The 43 : * DataBox tags are printed with nice indenting for easy readability in the 44 : * stdout file. 45 : * 46 : * This can be generalized in the future to other dimensions if needed. 47 : */ 48 1 : struct PrintElementInfo { 49 : template <typename ParallelComponent, typename DbTags, typename Metavariables, 50 : typename ArrayIndex> 51 0 : static void apply(db::DataBox<DbTags>& box, 52 : const Parallel::GlobalCache<Metavariables>& cache, 53 : const ArrayIndex& array_index) { 54 : auto& local_object = 55 : *Parallel::local(Parallel::get_parallel_component<ParallelComponent>( 56 : cache)[array_index]); 57 : 58 : const bool terminated = local_object.get_terminate(); 59 : 60 : std::stringstream ss{}; 61 : ss << std::scientific << std::setprecision(16); 62 : ss << "Element " << array_index 63 : << (terminated ? " terminated" : " did NOT terminate") << " at time " 64 : << db::get<::Tags::Time>(box) << "."; 65 : 66 : // Only print stuff if this element didn't terminate properly 67 : if (not terminated) { 68 : const std::string& next_action = 69 : local_object.deadlock_analysis_next_iterable_action(); 70 : ss << " Next action: " << next_action << "\n"; 71 : 72 : // Start with time step and next time 73 : const auto& step = db::get<::Tags::TimeStep>(box); 74 : // The time step only prints a slab (beginning/end) and a fraction so we 75 : // also print the approx numerical value of the step for easier reading 76 : ss << " Time step: " << step << ":" << step.value() << "\n"; 77 : ss << " Next time: " 78 : << db::get<::Tags::Next<::Tags::TimeStepId>>(box).substep_time() 79 : << "\n"; 80 : 81 : ss << " Inboxes:\n"; 82 : 83 : const auto& inboxes = local_object.get_inboxes(); 84 : 85 : const std::string mortar_inbox = Parallel::output_inbox< 86 : evolution::dg::Tags::BoundaryCorrectionAndGhostCellsInbox<3>>(inboxes, 87 : 2_st); 88 : ss << mortar_inbox; 89 : 90 : ss << " Mortars:\n"; 91 : 92 : const auto& mortar_next_temporal_id = 93 : db::get<evolution::dg::Tags::MortarNextTemporalId<3>>(box); 94 : 95 : ss << " MortarNextTemporalId\n"; 96 : for (const auto& [key, next_id] : mortar_next_temporal_id) { 97 : ss << " Key: " << key << ", next time: " << next_id.substep_time() 98 : << "\n"; 99 : } 100 : 101 : if constexpr (Metavariables::local_time_stepping) { 102 : const auto& mortar_data_history = 103 : db::get<evolution::dg::Tags::MortarDataHistory< 104 : 3, typename db::add_tag_prefix< 105 : ::Tags::dt, 106 : typename Metavariables::system::variables_tag>::type>>( 107 : box); 108 : ss << " MortarDataHistory:\n"; 109 : 110 : for (const auto& [key, history] : mortar_data_history) { 111 : ss << " Key: " << key << ", history:\n"; 112 : history.template print<false>(ss, 4_st); 113 : } 114 : } else { 115 : const auto& mortar_data = 116 : db::get<evolution::dg::Tags::MortarData<3>>(box); 117 : ss << " MortarData:\n"; 118 : 119 : for (const auto& [key, single_mortar_data] : mortar_data) { 120 : ss << " Key: " << key << ", mortar data:\n"; 121 : ss << single_mortar_data.pretty_print_current_buffer_no_data(4_st); 122 : } 123 : } 124 : } else { 125 : ss << "\n"; 126 : } 127 : 128 : Parallel::printf("%s", ss.str()); 129 : } 130 : }; 131 : } // namespace deadlock