Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
memory_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 // Local includes
19 #include "libmesh/memory_solution_history.h"
20 #include "libmesh/memory_history_data.h"
21 
22 #include "libmesh/diff_system.h"
23 
24 #include <cmath>
25 #include <iterator>
26 
27 namespace libMesh
28 {
29 
31 {
32 }
33 
34 // This functions saves all the projected system vectors for
35 // future use
36 void MemorySolutionHistory::store(bool /* is_adjoint_solve */, Real time)
37 {
38  this->find_stored_entry(time, true);
39 
40  // In an empty history we create the first entry
41  if (stored_data.begin() == stored_data.end())
42  {
43  stored_data[time] = std::make_unique<MemoryHistoryData>(_system);
44  stored_datum = stored_data.begin();
45  }
46 
47  // If we're past the end we can create a new entry
48  if (time - stored_datum->first > TOLERANCE )
49  {
50 #ifndef NDEBUG
51  ++stored_datum;
53 #endif
54  stored_data[time] = std::make_unique<MemoryHistoryData>(_system);
55  stored_datum = stored_data.end();
56  --stored_datum;
57  }
58 
59  // If we're before the beginning we can create a new entry
60  else if (stored_datum->first - time > TOLERANCE)
61  {
63  stored_data[time] = std::make_unique<MemoryHistoryData>(_system);
64  stored_datum = stored_data.begin();
65  }
66 
67  // We don't support inserting entries elsewhere
68  libmesh_assert(std::abs(stored_datum->first - time) < TOLERANCE);
69 
70  // First we handle the case of the initial data, this is the only case in which
71  // stored_data will have size one
72  if(stored_data.size() == 1)
73  {
74  // The initial data should only be stored once.
75  (stored_datum->second)->store_initial_solution();
76  }
77  else if((stored_datum->second)->get_previously_stored() == false) // If we are not at the initial time, we are either creating a new entry or overwriting an existing one
78  {
79  (stored_datum->second)->store_primal_solution(stored_datum);
80  }
81  else // We are overwriting an existing history data
82  {
83  (stored_datum->second)->rewrite_stored_solution();
84  }
85 }
86 
87 void MemorySolutionHistory::retrieve(bool is_adjoint_solve, Real time)
88 {
89  this->find_stored_entry(time, false);
90 
91  // If we are solving the adjoint, the timestep we need to move to the past step
92  // is the one taken at that step to get to the current time.
93  // At the initial time, be ready for the primal time march again.
94  if(is_adjoint_solve)
95  {
96  if( stored_datum != stored_data.begin() )
97  {
98  stored_data_iterator stored_datum_past = stored_datum;
99  stored_datum_past--;
100 
101  _system.deltat = (stored_datum_past->second)->get_deltat_at();
102  }
103  else
104  {
105  _system.deltat = (stored_datum->second)->get_deltat_at();
106  }
107  }
108  else
109  {
110  if( stored_datum != std::prev(stored_data.end()) )
111  _system.deltat = (stored_datum->second)->get_deltat_at();
112  else
113  {
114  stored_data_iterator stored_datum_past = stored_datum;
115  stored_datum_past--;
116 
117  _system.deltat = (stored_datum_past->second)->get_deltat_at();
118  }
119 
120  }
121 
122  // Get the time at which we are recovering the solution vectors
123  Real recovery_time = stored_datum->first;
124 
125  // Print out what time we are recovering vectors at
126  // libMesh::out << "Recovering solution vectors at time: " <<
127  // recovery_time << std::endl;
128 
129  // Do we not have a solution for this time? Then
130  // there's nothing to do.
131  if (stored_datum == stored_data.end() ||
132  std::abs(recovery_time - time) > TOLERANCE)
133  {
134  //libMesh::out << "No more solutions to recover ! We are at time t = " <<
135  // _system.time << std::endl;
136  return;
137  }
138 
139  (stored_datum->second)->retrieve_primal_solution();
140 
141  // We need to call update to put system in a consistent state
142  // with the solution that was read in
143  _system.update();
144 }
145 
146 }
static constexpr Real TOLERANCE
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
The libMesh namespace provides an interface to certain functionality in the library.
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time...
Definition: diff_system.h:280
libmesh_assert(ctx)
virtual void store(bool is_adjoint_solve, Real time) override
Virtual function store which we will be overriding to store timesteps.
virtual void retrieve(bool is_adjoint_solve, Real time) override
Virtual function retrieve which we will be overriding to retrieve timesteps.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:497
map_type::iterator stored_data_iterator
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
stored_data_iterator stored_datum
void find_stored_entry(Real time, bool storing=false)