Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : // MOOSE Includes 13 : #include "MooseTypes.h" 14 : #include "MooseError.h" 15 : #include "SolutionInvalidityRegistry.h" 16 : #include "ConsoleStream.h" 17 : #include "ConsoleStreamInterface.h" 18 : 19 : // System Includes 20 : #include <array> 21 : #include <atomic> 22 : #include <thread> 23 : #include <future> 24 : #include <mutex> 25 : 26 : // libMesh Includes 27 : #include "libmesh/parallel_object.h" 28 : 29 : // Forward Declarations 30 : template <class... Ts> 31 : class VariadicTable; 32 : 33 : /** 34 : * The SolutionInvalidity will contain all the information about the occurrence(s) of solution 35 : * invalidity 36 : */ 37 : class SolutionInvalidity : protected ConsoleStreamInterface, public libMesh::ParallelObject 38 : { 39 : public: 40 : using SolutionInvalidityRegistry = moose::internal::SolutionInvalidityRegistry; 41 : 42 : /** 43 : * Create a new SolutionInvalidity 44 : */ 45 : SolutionInvalidity(MooseApp & app); 46 : 47 : /// Increments solution invalid occurrences for each solution id 48 : void flagInvalidSolutionInternal(const InvalidSolutionID _invalid_solution_id); 49 : 50 : /** 51 : * Whether or not an invalid solution was encountered that was a warning. 52 : * 53 : * This must be called after a sync. 54 : */ 55 : bool hasInvalidSolutionWarning() const; 56 : 57 : /** 58 : * Whether or not an invalid solution was encountered that was an error. 59 : * 60 : * This must be called after a sync. 61 : */ 62 : bool hasInvalidSolutionError() const; 63 : 64 : /** 65 : * Whether or not any invalid solution was encountered (error or warning). 66 : * 67 : * This must be called after a sync. 68 : */ 69 : bool hasInvalidSolution() const; 70 : 71 : /// Reset the number of solution invalid occurrences back to zero for the current time step 72 : void resetSolutionInvalidTimeStep(); 73 : 74 : /// Reset the number of solution invalid occurrences back to zero 75 : void resetSolutionInvalidCurrentIteration(); 76 : 77 : /// Pass the number of solution invalid occurrences from current iteration to cumulative counters 78 : void solutionInvalidAccumulation(); 79 : 80 : /// Pass the number of solution invalid occurrences from current iteration to cumulative time iteration counters 81 : void solutionInvalidAccumulationTimeStep(const unsigned int timestep_index); 82 : 83 : /// Compute the total number of solution invalid occurrences 84 : void computeTotalCounts(); 85 : 86 : /// Struct used in InvalidCounts for storing the time history of invalid occurrences 87 : struct TimestepCounts 88 : { 89 30 : TimestepCounts() : timestep_index(std::numeric_limits<unsigned int>::max()) {} 90 245 : TimestepCounts(unsigned int timestep_index) : timestep_index(timestep_index) {} 91 : unsigned int timestep_index; 92 : unsigned int counts = 0; 93 : }; 94 : 95 : /// Struct used in _counts for storing invalid occurrences 96 : struct InvalidCounts 97 : { 98 : unsigned int current_counts = 0; 99 : unsigned int current_timestep_counts = 0; 100 : unsigned int total_counts = 0; 101 : std::vector<TimestepCounts> timestep_counts; 102 : }; 103 : 104 : /// Access the private solution invalidity counts 105 184 : const std::vector<InvalidCounts> & counts() const { return _counts; } 106 : 107 : /** 108 : * Print the summary table of Solution Invalid warnings 109 : * @param console The output stream to output to 110 : */ 111 : void print(const ConsoleStream & console) const; 112 : 113 : /** 114 : * Print the time history table of Solution Invalid warnings 115 : * @param console The output stream to output to 116 : */ 117 : void printHistory(const ConsoleStream & console, unsigned int & timestep_interval_size) const; 118 : 119 : /** 120 : * Immediately print the section and message for debug purpose 121 : */ 122 : void printDebug(InvalidSolutionID _invalid_solution_id) const; 123 : 124 : /** 125 : * Sync iteration counts to main processor 126 : */ 127 : void syncIteration(); 128 : 129 : friend void dataStore(std::ostream &, SolutionInvalidity &, void *); 130 : friend void dataLoad(std::istream &, SolutionInvalidity &, void *); 131 : 132 : private: 133 : /// Mutex for locking access to the invalid counts 134 : /// TODO: These can be changed to shared_mutexes 135 : mutable std::mutex _invalid_mutex; 136 : 137 : typedef VariadicTable<std::string, 138 : unsigned long int, 139 : unsigned long int, 140 : unsigned long int, 141 : std::string> 142 : FullTable; 143 : 144 : /// Build a VariadicTable for solution invalidity 145 : FullTable summaryTable() const; 146 : 147 : typedef VariadicTable<std::string, std::string, unsigned long int, unsigned long int> TimeTable; 148 : 149 : /// Build a VariadicTable for solution invalidity history 150 : TimeTable transientTable(unsigned int & time_interval) const; 151 : 152 : /// Create a registry to keep track of the names and occurrences of the solution invalidity 153 : SolutionInvalidityRegistry & _solution_invalidity_registry; 154 : 155 : /// Store the solution invalidity counts 156 : std::vector<InvalidCounts> _counts; 157 : 158 : /// Whether or not we've synced (can check counts/existance of warnings or errors) 159 : bool _has_synced; 160 : /// Whether or not we have a warning (only after a sync) 161 : bool _has_solution_warning; 162 : /// Whether or not we have an invalid solution (only after a sync) 163 : bool _has_solution_error; 164 : }; 165 : 166 : // datastore and dataload for recover 167 : void dataStore(std::ostream & stream, 168 : SolutionInvalidity::TimestepCounts & timestep_counts, 169 : void * context); 170 : void dataLoad(std::istream & stream, 171 : SolutionInvalidity::TimestepCounts & timestep_counts, 172 : void * context); 173 : void dataStore(std::ostream & stream, SolutionInvalidity & solution_invalidity, void * context); 174 : void dataLoad(std::istream & stream, SolutionInvalidity & solution_invalidity, void * context);