24 #include "libmesh/parallel_algebra.h" 25 #include "libmesh/parallel_sync.h" 29 ParallelObject(app.comm()),
32 _has_solution_warning(false),
33 _has_solution_error(false)
41 if (
_counts.size() <= _invalid_solution_id)
42 _counts.resize(_invalid_solution_id + 1);
44 ++
_counts[_invalid_solution_id].current_counts;
72 entry.current_counts = 0;
82 entry.current_timestep_counts = 0;
89 entry.current_timestep_counts += entry.current_counts;
96 if (entry.current_timestep_counts)
98 if (entry.timestep_counts.empty() ||
99 entry.timestep_counts.back().timestep_index != timestep_index)
100 entry.timestep_counts.emplace_back(timestep_index);
101 entry.timestep_counts.back().counts = entry.current_timestep_counts;
102 entry.total_counts += entry.current_timestep_counts;
113 entry.total_counts = 0;
114 for (
auto & time_counts : entry.timestep_counts)
115 entry.total_counts += time_counts.counts;
122 console <<
"\nSolution Invalid Warnings:\n";
128 unsigned int & timestep_interval_size)
const 130 console <<
"\nSolution Invalid Warnings History:\n";
137 std::map<processor_id_type, std::vector<std::tuple<std::string, std::string, int, unsigned int>>>
147 if (entry.current_counts)
150 data_to_send[0].emplace_back(
151 info.object_type,
info.message,
info.warning, entry.current_counts);
152 entry.current_counts = 0;
156 const auto receive_data = [
this](
const processor_id_type libmesh_dbg_var(pid),
const auto & data)
158 mooseAssert(
processor_id() == 0,
"Should only receive on processor 0");
160 for (
const auto & [object_type, message, warning_int,
counts] : data)
162 mooseAssert(
counts,
"Should not send data without counts");
166 const bool warning = warning_int;
174 "Inconsistent registration of invalidity warning and error");
178 mooseAssert(pid != 0,
"Should only hit on other processors");
180 object_type, message, warning);
217 FullTable vtable({
"Object",
"Converged",
"Timestep",
"Total",
"Message"}, 4);
227 vtable.setColumnPrecision({
239 const auto & entry =
_counts[id];
240 if (entry.current_counts)
243 vtable.addRow(
info.object_type,
244 entry.current_counts,
245 entry.current_timestep_counts,
261 TimeTable vtable({
"Object",
"Time",
"Stepinterval Count",
"Total Count"}, 4);
270 vtable.setColumnPrecision({
281 const auto & entry =
_counts[id];
283 std::vector<unsigned int> interval_counts;
284 std::vector<unsigned int> total_counts;
286 if (!entry.timestep_counts.empty())
288 for (
unsigned int timestep = 0; timestep < entry.timestep_counts.back().timestep_index;
289 timestep += step_interval)
292 auto start_it = timestep;
293 auto end_it = (timestep + step_interval < entry.timestep_counts.back().timestep_index)
294 ? start_it + step_interval
295 : entry.timestep_counts.back().timestep_index;
297 int interval_sum = 0;
298 for (
auto ts_count : entry.timestep_counts)
300 if (ts_count.timestep_index >= start_it && ts_count.timestep_index < end_it)
301 interval_sum += ts_count.counts;
304 interval_counts.push_back(interval_sum);
308 unsigned int interval_sum = 0;
309 for (
unsigned int interval_index :
index_range(interval_counts))
311 std::string interval_index_str =
312 std::to_string(interval_index) +
"-" + std::to_string(interval_index + step_interval);
314 interval_sum += interval_counts[interval_index];
315 vtable.addRow(
info.object_type +
" : " +
info.message,
317 interval_counts[interval_index],
356 std::size_t size = solution_invalidity.
_counts.size();
361 auto & entry = solution_invalidity.
_counts[id];
363 std::string type =
info.object_type;
364 std::string message =
info.message;
365 bool warning =
info.warning;
369 dataStore(stream, entry.current_counts, context);
370 dataStore(stream, entry.current_timestep_counts, context);
371 dataStore(stream, entry.timestep_counts, context);
372 dataStore(stream, entry.total_counts, context);
382 std::size_t num_counts;
384 dataLoad(stream, num_counts, context);
386 std::string object_type, message;
391 for (
size_t i = 0; i < num_counts; i++)
393 dataLoad(stream, object_type, context);
402 object_type, message, warning);
404 if (solution_invalidity.
_counts.size() <= id)
405 solution_invalidity.
_counts.resize(
id + 1);
407 auto & entry = solution_invalidity.
_counts[id];
408 dataLoad(stream, entry.current_counts, context);
409 dataLoad(stream, entry.current_timestep_counts, context);
410 dataLoad(stream, entry.timestep_counts, context);
411 dataLoad(stream, entry.total_counts, context);
std::string name(const ElemQuality q)
void computeTotalCounts()
Compute the total number of solution invalid occurrences.
bool hasInvalidSolutionError() const
Whether or not an invalid solution was encountered that was an error.
A helper class for re-directing output streams to Console output objects form MooseObjects.
void dataStore(std::ostream &stream, SolutionInvalidity::TimestepCounts ×tep_counts, void *context)
void solutionInvalidAccumulationTimeStep(const unsigned int timestep_index)
Pass the number of solution invalid occurrences from current iteration to cumulative time iteration c...
bool hasInvalidSolutionWarning() const
Whether or not an invalid solution was encountered that was a warning.
std::mutex _invalid_mutex
Mutex for locking access to the invalid counts TODO: These can be changed to shared_mutexes.
const std::vector< InvalidCounts > & counts() const
Access the private solution invalidity counts.
void print(StreamType &stream)
Pretty print the table of data.
unsigned int InvalidSolutionID
std::vector< InvalidCounts > _counts
Store the solution invalidity counts.
void dataLoad(std::istream &stream, SolutionInvalidity::TimestepCounts ×tep_counts, void *context)
SolutionInvalidity(MooseApp &app)
Create a new SolutionInvalidity.
bool _has_synced
Whether or not we've synced (can check counts/existance of warnings or errors)
A class for "pretty printing" a table of data.
void resetSolutionInvalidTimeStep()
Reset the number of solution invalid occurrences back to zero for the current time step...
void printDebug(InvalidSolutionID _invalid_solution_id) const
Immediately print the section and message for debug purpose.
Base class for MOOSE-based applications.
SolutionInvalidityRegistry & _solution_invalidity_registry
Create a registry to keep track of the names and occurrences of the solution invalidity.
const Parallel::Communicator & comm() const
InvalidSolutionID registerInvalidity(const std::string &object_type, const std::string &message, const bool warning)
Call to register an invalid calculation.
TimeTable transientTable(unsigned int &time_interval) const
Build a VariadicTable for solution invalidity history.
unsigned int timestep_index
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
void solutionInvalidAccumulation()
Pass the number of solution invalid occurrences from current iteration to cumulative counters...
uint8_t processor_id_type
void syncIteration()
Sync iteration counts to main processor.
std::size_t id(const Key &key) const
bool _has_solution_warning
Whether or not we have a warning (only after a sync)
const Item & item(const std::size_t id) const
An inteface for the _console for outputting to the Console object.
bool hasInvalidSolution() const
Whether or not any invalid solution was encountered (error or warning).
Helper class that stores the name associated with an invalid solution.
void flagInvalidSolutionInternal(const InvalidSolutionID _invalid_solution_id)
Increments solution invalid occurrences for each solution id.
void setColumnFormat(const std::vector< VariadicTableColumnFormat > &column_format)
Set how to format numbers for each column.
bool _has_solution_error
Whether or not we have an invalid solution (only after a sync)
The SolutionInvalidity will contain all the information about the occurrence(s) of solution invalidit...
Struct used in InvalidCounts for storing the time history of invalid occurrences. ...
SolutionInvalidityRegistry & getSolutionInvalidityRegistry()
Get the global SolutionInvalidityRegistry singleton.
void max(const T &r, T &o, Request &req) const
void print(const ConsoleStream &console) const
Print the summary table of Solution Invalid warnings.
bool keyExists(const Key &key) const
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
void resetSolutionInvalidCurrentIteration()
Reset the number of solution invalid occurrences back to zero.
void printHistory(const ConsoleStream &console, unsigned int ×tep_interval_size) const
Print the time history table of Solution Invalid warnings.
processor_id_type processor_id() const
auto index_range(const T &sizable)
FullTable summaryTable() const
Build a VariadicTable for solution invalidity.