libMesh
memory_solution_history.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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 // Local includes
19 #include "libmesh/memory_solution_history.h"
20 
21 #include <cmath>
22 
23 namespace libMesh
24 {
25 // The Destructor
27 {
28  stored_solutions_iterator stored_sols_it = stored_solutions.begin();
29  const stored_solutions_iterator stored_sols_end = stored_solutions.end();
30 
31  for (; stored_sols_it != stored_sols_end; ++stored_sols_it)
32  {
33  // The saved vectors at this timestep
34  std::map<std::string, NumericVector<Number> *> saved_vectors = stored_sols_it->second;
35 
36  std::map<std::string, NumericVector<Number> *>::iterator vec = saved_vectors.begin();
37  std::map<std::string, NumericVector<Number> *>::iterator vec_end = saved_vectors.end();
38 
39  // Loop over all the saved vectors
40  for (; vec != vec_end; ++vec)
41  {
42  // Delete this saved vector
43  delete vec->second;
44  }
45  }
46 }
47 
48 // This function finds, if it can, the entry where we're supposed to
49 // be storing data
51 {
52  if (stored_solutions.begin() == stored_solutions.end())
53  return;
54 
56 
57  if (std::abs(stored_sols->first - _system.time) < TOLERANCE)
58  return;
59 
60  // If we're not at the front, check the previous entry
61  if (stored_sols != stored_solutions.begin())
62  {
64  if (std::abs((--test_it)->first - _system.time) < TOLERANCE)
65  {
66  --stored_sols;
67  return;
68  }
69  }
70 
71  // If we're not at the end, check the subsequent entry
73  if ((++test_it) != stored_solutions.end())
74  {
75  if (std::abs(test_it->first - _system.time) < TOLERANCE)
76  {
77  ++stored_sols;
78  return;
79  }
80  }
81 }
82 
83 // This functions saves all the 'projection-worthy' system vectors for
84 // future use
86 {
87  this->find_stored_entry();
88 
89  // In an empty history we create the first entry
90  if (stored_solutions.begin() == stored_solutions.end())
91  {
92  stored_solutions.push_back
93  (std::make_pair(_system.time,
94  std::map<std::string, NumericVector<Number> *>()));
95  stored_sols = stored_solutions.begin();
96  }
97 
98  // If we're past the end we can create a new entry
99  if (_system.time - stored_sols->first > TOLERANCE )
100  {
101 #ifndef NDEBUG
102  ++stored_sols;
104 #endif
105  stored_solutions.push_back
106  (std::make_pair(_system.time,
107  std::map<std::string, NumericVector<Number> *>()));
109  --stored_sols;
110  }
111 
112  // If we're before the beginning we can create a new entry
113  else if (stored_sols->first - _system.time > TOLERANCE)
114  {
116  stored_solutions.push_front
117  (std::make_pair(_system.time,
118  std::map<std::string, NumericVector<Number> *>()));
119  stored_sols = stored_solutions.begin();
120  }
121 
122  // We don't support inserting entries elsewhere
124 
125  // Map of stored vectors for this solution step
126  std::map<std::string, NumericVector<Number> *> & saved_vectors = stored_sols->second;
127 
128  // Loop over all the system vectors
129  for (System::vectors_iterator vec = _system.vectors_begin(); vec != _system.vectors_end(); ++vec)
130  {
131  // The name of this vector
132  const std::string & vec_name = vec->first;
133 
134  // If we haven't seen this vector before or if we have and
135  // want to overwrite it
137  !saved_vectors.count(vec_name)) &&
138  // and if we think it's worth preserving
139  _system.vector_preservation(vec_name))
140  {
141  // Then we save it.
142  saved_vectors[vec_name] = vec->second->clone().release();
143  }
144  }
145 
146  // Of course, we will usually save the actual solution
147  std::string _solution("_solution");
149  !saved_vectors.count(_solution)) &&
150  // and if we think it's worth preserving
152  saved_vectors[_solution] = _system.solution->clone().release();
153 }
154 
156 {
157  this->find_stored_entry();
158 
159  // Get the time at which we are recovering the solution vectors
160  Real recovery_time = stored_sols->first;
161 
162  // Print out what time we are recovering vectors at
163  // libMesh::out << "Recovering solution vectors at time: " <<
164  // recovery_time << std::endl;
165 
166  // Do we not have a solution for this time? Then
167  // there's nothing to do.
168  if (stored_sols == stored_solutions.end() ||
169  std::abs(recovery_time - _system.time) > TOLERANCE)
170  {
171  //libMesh::out << "No more solutions to recover ! We are at time t = " <<
172  // _system.time << std::endl;
173  return;
174  }
175 
176  // Get the saved vectors at this timestep
177  std::map<std::string, NumericVector<Number> *> & saved_vectors = stored_sols->second;
178 
179  std::map<std::string, NumericVector<Number> *>::iterator vec = saved_vectors.begin();
180  std::map<std::string, NumericVector<Number> *>::iterator vec_end = saved_vectors.end();
181 
182  // Loop over all the saved vectors
183  for (; vec != vec_end; ++vec)
184  {
185  // The name of this vector
186  const std::string & vec_name = vec->first;
187 
188  // Get the vec_name entry in the saved vectors map and set the
189  // current system vec[vec_name] entry to it
190  if (vec_name != "_solution")
191  _system.get_vector(vec_name) = *(vec->second);
192  }
193 
194  // Of course, we will *always* have to get the actual solution
195  std::string _solution("_solution");
196  *(_system.solution) = *(saved_vectors[_solution]);
197 }
198 
199 }
200 // End namespace libMesh
vectors_iterator vectors_end()
End of vectors container.
Definition: system.h:2238
Real time
For time-dependent problems, this is the time t at the beginning of the current timestep.
Definition: system.h:1545
double abs(double a)
std::list< std::pair< Real, std::map< std::string, NumericVector< Number > * > > >::iterator stored_solutions_iterator
Typedef for Stored Solutions iterator, a list of pairs of the current system time, map of strings and saved vectors.
std::list< std::pair< Real, std::map< std::string, NumericVector< Number > * > > > stored_solutions
bool vector_preservation(const std::string &vec_name) const
Definition: system.C:895
static const Real TOLERANCE
The libMesh namespace provides an interface to certain functionality in the library.
vectors_iterator vectors_begin()
Beginning of vectors container.
Definition: system.h:2226
libmesh_assert(j)
virtual void store() libmesh_override
Virtual function store which we will be overriding to store timesteps.
virtual void retrieve() libmesh_override
Virtual function retrieve which we will be overriding to retrieve timesteps.
stored_solutions_iterator stored_sols
UniquePtr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1523
const NumericVector< Number > & get_vector(const std::string &vec_name) const
Definition: system.C:794
std::map< std::string, NumericVector< Number > * >::iterator vectors_iterator
Vector iterator typedefs.
Definition: system.h:748
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool & project_solution_on_reinit(void)
Tells the System whether or not to project the solution vector onto new grids when the system is rein...
Definition: system.h:794