libMesh
Loading...
Searching...
No Matches
solution_history.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
22namespace 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.
28 {
29 if (stored_data.begin() == stored_data.end())
30 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 stored_data_iterator lower_bound_it = stored_data.lower_bound(time);
41
42 // For the key right before the lower bound
43 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 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 if(storing)
52 {
53 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 lower_bound_it = std::prev(lower_bound_it);
61 }
62 }
63 else if(lower_bound_it == stored_data.begin()) // At the beginning, so we cant go back any further
64 {
65 stored_datum = stored_data.begin();
66 return;
67 }
68 else // A decremented iterator, to perform the sandwich test for the key closest to time
69 {
70 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 if(std::abs(lower_bound_it->first - time) < TOLERANCE)
75 {
76 stored_datum = lower_bound_it;
77 }
78 else if(std::abs(lower_bound_it_decremented->first - time) < TOLERANCE)
79 {
80 stored_datum = lower_bound_it_decremented;
81 }
82 else // Neither of the two candidate keys matched our time
83 {
84 if(storing) // If we are storing, this is fine, we need to create a new entry, so just return
85 {
86 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 libmesh_error_msg("Failed to set stored solutions iterator to a valid value.");
91 }
92 }
93 }
94
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 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 this->find_stored_entry(time, false);
104
105 // map::erase behaviour is undefined if the iterator is pointing
106 // to a non-existent element.
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 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 if(stored_datum == stored_datum_last)
115 stored_datum--;
116
117 stored_data.erase(stored_datum_copy);
118 }
119
120}
121// End namespace libMesh
void find_stored_entry(Real time, bool storing=false)
map_type::iterator stored_data_iterator
void erase(Real time)
Erase stored_data entry at time.
stored_data_iterator stored_datum
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real