libMesh
src
solvers
solution_history.C
Go to the documentation of this file.
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
void
SolutionHistory::find_stored_entry
(
Real
time,
bool
storing)
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
95
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
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.
107
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
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
libMesh::TOLERANCE
static constexpr Real TOLERANCE
Definition:
libmesh_common.h:151
libMesh::MeshTools::Subdivision::prev
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
Definition:
mesh_subdivision_support.h:108
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
libMesh::SolutionHistory::erase
void erase(Real time)
Erase stored_data entry at time.
Definition:
solution_history.C:95
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::SolutionHistory::stored_data
map_type stored_data
Definition:
solution_history.h:94
libMesh::SolutionHistory::stored_data_iterator
map_type::iterator stored_data_iterator
Definition:
solution_history.h:95
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition:
libmesh_common.h:144
libMesh::SolutionHistory::stored_datum
stored_data_iterator stored_datum
Definition:
solution_history.h:96
libMesh::SolutionHistory::find_stored_entry
void find_stored_entry(Real time, bool storing=false)
Definition:
solution_history.C:27
Generated on Thu Jul 17 2025 01:29:10 for libMesh by
1.8.14