memory_solution_history.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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
20 
21 #include <cmath>
22 
23 namespace libMesh
24 {
25 
27 {
28 }
29 
30 // This function finds, if it can, the entry where we're supposed to
31 // be storing data
33 {
34  if (stored_solutions.begin() == stored_solutions.end())
35  return;
36 
37  libmesh_assert (stored_sols != stored_solutions.end());
38 
39  if (std::abs(stored_sols->first - _system.time) < TOLERANCE)
40  return;
41 
42  // If we're not at the front, check the previous entry
43  if (stored_sols != stored_solutions.begin())
44  {
46  if (std::abs((--test_it)->first - _system.time) < TOLERANCE)
47  {
48  --stored_sols;
49  return;
50  }
51  }
52 
53  // If we're not at the end, check the subsequent entry
55  if ((++test_it) != stored_solutions.end())
56  {
57  if (std::abs(test_it->first - _system.time) < TOLERANCE)
58  {
59  ++stored_sols;
60  return;
61  }
62  }
63 }
64 
65 // This functions saves all the 'projection-worthy' system vectors for
66 // future use
68 {
69  this->find_stored_entry();
70 
71  // In an empty history we create the first entry
72  if (stored_solutions.begin() == stored_solutions.end())
73  {
74  stored_solutions.push_back(std::make_pair(_system.time, map_type()));
75  stored_sols = stored_solutions.begin();
76  }
77 
78  // If we're past the end we can create a new entry
79  if (_system.time - stored_sols->first > TOLERANCE )
80  {
81 #ifndef NDEBUG
82  ++stored_sols;
83  libmesh_assert (stored_sols == stored_solutions.end());
84 #endif
85  stored_solutions.push_back(std::make_pair(_system.time, map_type()));
87  --stored_sols;
88  }
89 
90  // If we're before the beginning we can create a new entry
91  else if (stored_sols->first - _system.time > TOLERANCE)
92  {
93  libmesh_assert (stored_sols == stored_solutions.begin());
94  stored_solutions.push_front(std::make_pair(_system.time, map_type()));
95  stored_sols = stored_solutions.begin();
96  }
97 
98  // We don't support inserting entries elsewhere
99  libmesh_assert(std::abs(stored_sols->first - _system.time) < TOLERANCE);
100 
101  // Map of stored vectors for this solution step
102  std::map<std::string, std::unique_ptr<NumericVector<Number>>> & saved_vectors = stored_sols->second;
103 
104  // Loop over all the system vectors
105  for (System::vectors_iterator vec = _system.vectors_begin(); vec != _system.vectors_end(); ++vec)
106  {
107  // The name of this vector
108  const std::string & vec_name = vec->first;
109 
110  // If we haven't seen this vector before or if we have and
111  // want to overwrite it
112  if ((overwrite_previously_stored || !saved_vectors.count(vec_name)) &&
113  // and if we think it's worth preserving
114  _system.vector_preservation(vec_name))
115  {
116  // Then we save it.
117  saved_vectors[vec_name] = vec->second->clone();
118  }
119  }
120 
121  // Of course, we will usually save the actual solution
122  std::string _solution("_solution");
123  if ((overwrite_previously_stored || !saved_vectors.count(_solution)) &&
124  // and if we think it's worth preserving
126  saved_vectors[_solution] = _system.solution->clone();
127 }
128 
130 {
131  this->find_stored_entry();
132 
133  // Get the time at which we are recovering the solution vectors
134  Real recovery_time = stored_sols->first;
135 
136  // Print out what time we are recovering vectors at
137  // libMesh::out << "Recovering solution vectors at time: " <<
138  // recovery_time << std::endl;
139 
140  // Do we not have a solution for this time? Then
141  // there's nothing to do.
142  if (stored_sols == stored_solutions.end() ||
143  std::abs(recovery_time - _system.time) > TOLERANCE)
144  {
145  //libMesh::out << "No more solutions to recover ! We are at time t = " <<
146  // _system.time << std::endl;
147  return;
148  }
149 
150  // Get the saved vectors at this timestep
151  map_type & saved_vectors = stored_sols->second;
152 
153  map_type::iterator vec = saved_vectors.begin();
154  map_type::iterator vec_end = saved_vectors.end();
155 
156  // Loop over all the saved vectors
157  for (; vec != vec_end; ++vec)
158  {
159  // The name of this vector
160  const std::string & vec_name = vec->first;
161 
162  // Get the vec_name entry in the saved vectors map and set the
163  // current system vec[vec_name] entry to it
164  if (vec_name != "_solution")
165  _system.get_vector(vec_name) = *(vec->second);
166  }
167 
168  // Of course, we will *always* have to get the actual solution
169  std::string _solution("_solution");
170  *(_system.solution) = *(saved_vectors[_solution]);
171 }
172 
173 }
vectors_iterator vectors_end()
Definition: system.h:2257
double abs(double a)
static const Real TOLERANCE
vectors_iterator vectors_begin()
Definition: system.h:2245
bool vector_preservation(const std::string &vec_name) const
Definition: system.C:875
stored_solutions_iterator stored_sols
const NumericVector< Number > & get_vector(const std::string &vec_name) const
Definition: system.C:774
std::unique_ptr< NumericVector< Number > > solution
Definition: system.h:1523
std::map< std::string, std::unique_ptr< NumericVector< Number > > > map_type
std::map< std::string, NumericVector< Number > * >::iterator vectors_iterator
Definition: system.h:748
list_type::iterator stored_solutions_iterator
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool & project_solution_on_reinit(void)
Definition: system.h:794