LCOV - code coverage report
Current view: top level - src/solvers - solution_history.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 16 29 55.2 %
Date: 2025-08-19 19:27:09 Functions: 1 2 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : #include "libmesh/solution_history.h"
      19             : #include <cmath>
      20             : #include <iterator>
      21             : 
      22             : namespace libMesh
      23             : {
      24             :  // This function finds, if it can, the entry where we're supposed to
      25             :  // be storing data, leaves stored_datum unchanged if it cant find an entry
      26             :  // with the key corresponding to time.
      27       59360 :  void SolutionHistory::find_stored_entry(Real time, bool storing)
      28             :  {
      29       59360 :   if (stored_data.begin() == stored_data.end())
      30         448 :     return;
      31             : 
      32             :   // We will use the map::lower_bound operation to find the key which
      33             :   // is the least upper bound among all existing keys for time.
      34             :   // (key before map::lower_bound) < time < map::lower_bound, one of these
      35             :   // should be within TOLERANCE of time (unless we are creating a new map entry)
      36             :   // If the lower bound iterator points to:
      37             :   // begin -> we are looking for the solution at the initial time
      38             :   // end -> we are creating a new entry
      39             :   // anything else, we are looking for an existing entry
      40        1672 :   stored_data_iterator lower_bound_it = stored_data.lower_bound(time);
      41             : 
      42             :   // For the key right before the lower bound
      43        1672 :   stored_data_iterator lower_bound_it_decremented;
      44             : 
      45             :   // If we are at end, we could be creating a new entry (depends on the storing bool), return
      46             :   // Otherwise, get a decremented iterator for the sandwich test
      47       58520 :   if(lower_bound_it == stored_data.end())
      48             :   {
      49             :     // If we are storing and lower_bound_it points to stored_data.end(), we assume
      50             :     // that this is a brand new entry in the map. We leave stored_datum unchanged.
      51       11760 :     if(storing)
      52             :     {
      53         336 :       return;
      54             :     }
      55             :     else
      56             :     {
      57             :       // We are trying to retrieve and none of the keys was an upper bound.
      58             :       // We could have a situation in which the time is greatest key + FPE.
      59             :       // So we can check the key before the end and see if it matches time, else we have an error.
      60           0 :       lower_bound_it = std::prev(lower_bound_it);
      61             :     }
      62             :   }
      63       46760 :   else if(lower_bound_it == stored_data.begin()) // At the beginning, so we cant go back any further
      64             :   {
      65        3080 :     stored_datum = stored_data.begin();
      66        3080 :     return;
      67             :   }
      68             :   else // A decremented iterator, to perform the sandwich test for the key closest to time
      69             :   {
      70       43680 :     lower_bound_it_decremented = std::prev(lower_bound_it);
      71             :   }
      72             : 
      73             :   // Set the stored sols iterator as per the key which is within TOLERANCE of time
      74       44928 :   if(std::abs(lower_bound_it->first - time) < TOLERANCE)
      75             :   {
      76       36680 :     stored_datum = lower_bound_it;
      77             :   }
      78        7200 :   else if(std::abs(lower_bound_it_decremented->first - time) < TOLERANCE)
      79             :   {
      80        7000 :     stored_datum = lower_bound_it_decremented;
      81             :   }
      82             :   else // Neither of the two candidate keys matched our time
      83             :   {
      84           0 :     if(storing) // If we are storing, this is fine, we need to create a new entry, so just return
      85             :     {
      86           0 :       return;
      87             :     }
      88             :     else // If we are not storing, then we expected to find something but didn't, so we have a problem
      89             :     {
      90           0 :       libmesh_error_msg("Failed to set stored solutions iterator to a valid value.");
      91             :     }
      92             :   }
      93             :  }
      94             : 
      95           0 :  void SolutionHistory::erase(Real time)
      96             :  {
      97             :   // We cant erase the stored_datum iterator which is used in other places
      98             :   // So save its current value for the future
      99           0 :   stored_data_iterator stored_datum_last = stored_datum;
     100             :   //std::map<Real, unsigned int>::iterator timeTotimestamp_iterator_last = timeTotimestamp_iterator;
     101             : 
     102             :   // This will map the stored_datum iterator to the current time
     103           0 :   this->find_stored_entry(time, false);
     104             : 
     105             :   // map::erase behaviour is undefined if the iterator is pointing
     106             :   // to a non-existent element.
     107           0 :   libmesh_assert(stored_datum != stored_data.end());
     108             : 
     109             :   // We want to keep using the stored_datum iterator, so we have to create
     110             :   // a new one to erase the concerned entry
     111           0 :   stored_data_iterator stored_datum_copy = stored_datum;
     112             : 
     113             :   // If we're asking to erase the entry at stored_datum, then move stored_datum somewhere safer first
     114           0 :   if(stored_datum == stored_datum_last)
     115           0 :     stored_datum--;
     116             : 
     117           0 :   stored_data.erase(stored_datum_copy);
     118           0 :  }
     119             : 
     120             : }
     121             : // End namespace libMesh

Generated by: LCOV version 1.14