LCOV - code coverage report
Current view: top level - include/utils - SolutionInvalidity.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 4 4 100.0 %
Date: 2026-05-29 20:35:17 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          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             :   /**
      72             :    * Whether or not any warning or invalid solution has ever been encountered during the simulation
      73             :    *
      74             :    * This must be called after a sync.
      75             :    */
      76             :   bool hasEverHadSolutionIssue() const;
      77             : 
      78             :   /// Reset the number of solution invalid occurrences back to zero for the current time step
      79             :   void resetTimeStepOccurences();
      80             : 
      81             :   /// Reset the number of solution invalid occurrences back to zero
      82             :   void resetIterationOccurences();
      83             : 
      84             :   /// Pass the number of solution invalid occurrences from current iteration to cumulative counters
      85             :   void accumulateIterationIntoTimeStepOccurences();
      86             : 
      87             :   /// Pass the number of solution invalid occurrences from current timestep to cumulative timestep counter (e.g. the total)
      88             :   void accumulateTimeStepIntoTotalOccurences(const unsigned int timestep_index);
      89             : 
      90             :   /// Struct used in InvalidCounts for storing the time history of invalid occurrences
      91             :   struct TimestepCounts
      92             :   {
      93         186 :     TimestepCounts() : timestep_index(std::numeric_limits<unsigned int>::max()) {}
      94        1877 :     TimestepCounts(unsigned int timestep_index) : timestep_index(timestep_index) {}
      95             :     unsigned int timestep_index;
      96             :     unsigned int counts = 0;
      97             :   };
      98             : 
      99             :   /// Struct used in _counts for storing warning and invalid-solution occurrences
     100             :   struct InvalidCounts
     101             :   {
     102             :     /// Counts for the current iteration (depends on the count, but usually linear iteration)
     103             :     unsigned int current_counts = 0;
     104             :     /// Counts for the current time step
     105             :     unsigned int current_timestep_counts = 0;
     106             :     /// Total counts across the entire simulation
     107             :     unsigned int total_counts = 0;
     108             :     /// Keep track of the occurences across all time steps
     109             :     std::vector<TimestepCounts> timestep_counts;
     110             :   };
     111             : 
     112             :   /// Access the private solution invalidity counts
     113         166 :   const std::vector<InvalidCounts> & counts() const { return _counts; }
     114             : 
     115             :   /**
     116             :    * Print the summary table of Solution Invalid warnings
     117             :    * @param console The output stream to output to
     118             :    */
     119             :   void print(const ConsoleStream & console) const;
     120             : 
     121             :   /**
     122             :    * Print the time history table of Solution Invalid warnings
     123             :    * @param console The output stream to output to
     124             :    */
     125             :   void printHistory(const ConsoleStream & console, unsigned int & timestep_interval_size) const;
     126             : 
     127             :   /**
     128             :    * Immediately print the section and message for debug purpose
     129             :    */
     130             :   void printDebug(InvalidSolutionID _invalid_solution_id) const;
     131             : 
     132             :   /**
     133             :    * Sync iteration counts to main processor
     134             :    * Sum across all processors
     135             :    */
     136             :   void syncIteration();
     137             : 
     138             :   /// Whether the solution invalidity has synchronized iteration counts across MPI processes
     139      308629 :   bool hasSynced() const { return _has_synced; }
     140             : 
     141             :   friend void dataStore(std::ostream &, SolutionInvalidity &, void *);
     142             :   friend void dataLoad(std::istream &, SolutionInvalidity &, void *);
     143             : 
     144             : private:
     145             :   /// Mutex for locking access to the invalid counts
     146             :   /// TODO: These can be changed to shared_mutexes
     147             :   mutable std::mutex _invalid_mutex;
     148             : 
     149             :   typedef VariadicTable<std::string,
     150             :                         unsigned long int,
     151             :                         unsigned long int,
     152             :                         unsigned long int,
     153             :                         std::string>
     154             :       FullTable;
     155             : 
     156             :   /// Build a VariadicTable for solution invalidity
     157             :   FullTable summaryTable() const;
     158             : 
     159             :   typedef VariadicTable<std::string, std::string, unsigned long int, unsigned long int> TimeTable;
     160             : 
     161             :   /// Build a VariadicTable for solution invalidity history
     162             :   TimeTable transientTable(unsigned int & time_interval) const;
     163             : 
     164             :   /// Create a registry to keep track of the names and occurrences of the solution invalidity
     165             :   SolutionInvalidityRegistry & _solution_invalidity_registry;
     166             : 
     167             :   /// Store the solution invalidity counts
     168             :   std::vector<InvalidCounts> _counts;
     169             : 
     170             :   /// Whether or not we've synced (can check counts/existance of warnings or errors)
     171             :   bool _has_synced;
     172             :   /// Whether or not we have a warning (only after a sync)
     173             :   bool _has_solution_warning;
     174             :   /// Whether or not we have an invalid solution (only after a sync)
     175             :   bool _has_solution_error;
     176             :   /// Whether or not we have ever had any warning or solution issue during the simulation
     177             :   bool _has_recorded_issue;
     178             : };
     179             : 
     180             : // datastore and dataload for recover
     181             : void dataStore(std::ostream & stream,
     182             :                SolutionInvalidity::TimestepCounts & timestep_counts,
     183             :                void * context);
     184             : void dataLoad(std::istream & stream,
     185             :               SolutionInvalidity::TimestepCounts & timestep_counts,
     186             :               void * context);
     187             : void dataStore(std::ostream & stream, SolutionInvalidity & solution_invalidity, void * context);
     188             : void dataLoad(std::istream & stream, SolutionInvalidity & solution_invalidity, void * context);

Generated by: LCOV version 1.14