libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Attributes | List of all members
libMesh::FileSolutionHistory Class Reference

Subclass of Solution History that stores the solutions and other important vectors onto disk. More...

#include <file_solution_history.h>

Inheritance diagram for libMesh::FileSolutionHistory:
[legend]

Public Member Functions

 FileSolutionHistory (DifferentiableSystem &system)
 Constructor, reference to system to be passed by user, set the stored_sols iterator to some initial value.
 
 ~FileSolutionHistory ()
 Destructor, defaulted out-of-line.
 
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 std::unique_ptr< SolutionHistoryclone () const override
 Definition of the clone function needed for the setter function.
 
void erase (Real time)
 Erase stored_data entry at time.
 
void set_overwrite_previously_stored (bool val)
 Turn on overwrite_previously_stored to overwrite any already-saved data encountered during subsequent store() calls.
 

Protected Types

typedef std::map< Real, std::unique_ptr< HistoryData > > map_type
 
typedef map_type::iterator stored_data_iterator
 

Protected Member Functions

void find_stored_entry (Real time, bool storing=false)
 

Protected Attributes

bool overwrite_previously_stored
 
map_type stored_data
 
stored_data_iterator stored_datum
 

Private Attributes

DifferentiableSystem_system
 
std::vector< std::unique_ptr< NumericVector< Number > > > dual_solution_copies
 A vector of pointers to adjoint and old adjoint solutions at the last time step.
 
std::vector< std::unique_ptr< NumericVector< Number > > > old_dual_solution_copies
 

Detailed Description

Subclass of Solution History that stores the solutions and other important vectors onto disk.

Author
Vikram Garg
Date
2020

Stores past solutions onto disk.

Definition at line 46 of file file_solution_history.h.

Member Typedef Documentation

◆ map_type

typedef std::map<Real, std::unique_ptr<HistoryData> > libMesh::SolutionHistory::map_type
protectedinherited

Definition at line 93 of file solution_history.h.

◆ stored_data_iterator

typedef map_type::iterator libMesh::SolutionHistory::stored_data_iterator
protectedinherited

Definition at line 95 of file solution_history.h.

Constructor & Destructor Documentation

◆ FileSolutionHistory()

libMesh::FileSolutionHistory::FileSolutionHistory ( DifferentiableSystem system)

Constructor, reference to system to be passed by user, set the stored_sols iterator to some initial value.

Constructor, reference to system to be passed by user, set the stored_datum iterator to some initial value.

Definition at line 36 of file file_solution_history.C.

37 : SolutionHistory(), _system(system)
38{
41
42 libmesh_experimental();
43}
std::vector< std::unique_ptr< NumericVector< Number > > > dual_solution_copies
A vector of pointers to adjoint and old adjoint solutions at the last time step.
std::vector< std::unique_ptr< NumericVector< Number > > > old_dual_solution_copies
unsigned int n_qois() const
Number of currently active quantities of interest.
Definition system.h:2562

References _system, dual_solution_copies, libMesh::System::n_qois(), and old_dual_solution_copies.

◆ ~FileSolutionHistory()

libMesh::FileSolutionHistory::~FileSolutionHistory ( )
default

Destructor, defaulted out-of-line.

Member Function Documentation

◆ clone()

std::unique_ptr< SolutionHistory > libMesh::FileSolutionHistory::clone ( ) const
overridevirtual

Definition of the clone function needed for the setter function.

Implements libMesh::SolutionHistory.

Definition at line 49 of file file_solution_history.C.

50{
51 return std::make_unique<FileSolutionHistory>(_system);
52}

References _system.

◆ erase()

void libMesh::SolutionHistory::erase ( Real  time)
inherited

Erase stored_data entry at time.

Definition at line 95 of file solution_history.C.

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 }
void find_stored_entry(Real time, bool storing=false)
map_type::iterator stored_data_iterator
stored_data_iterator stored_datum
libmesh_assert(ctx)

References libMesh::SolutionHistory::find_stored_entry(), libMesh::libmesh_assert(), libMesh::SolutionHistory::stored_data, and libMesh::SolutionHistory::stored_datum.

◆ find_stored_entry()

void libMesh::SolutionHistory::find_stored_entry ( Real  time,
bool  storing = false 
)
protectedinherited

Definition at line 27 of file solution_history.C.

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 }
static constexpr Real TOLERANCE

References libMesh::SolutionHistory::stored_data, libMesh::SolutionHistory::stored_datum, and libMesh::TOLERANCE.

Referenced by libMesh::SolutionHistory::erase(), retrieve(), libMesh::MemorySolutionHistory::retrieve(), store(), and libMesh::MemorySolutionHistory::store().

◆ retrieve()

void libMesh::FileSolutionHistory::retrieve ( bool  is_adjoint_solve,
Real  time 
)
overridevirtual

Virtual function retrieve which we will be overriding to retrieve timesteps.

Implements libMesh::SolutionHistory.

Definition at line 116 of file file_solution_history.C.

117{
118 this->find_stored_entry(time, false);
119
120 // If we are solving the adjoint, the timestep we need to move to the past step
121 // is the one taken at that step to get to the current time.
122 // At the initial time, be ready for the primal time march again.
123 if(is_adjoint_solve)
124 {
125 if( stored_datum != stored_data.begin() )
126 {
127 stored_data_iterator stored_datum_past = stored_datum;
128 stored_datum_past--;
129
130 _system.deltat = (stored_datum_past->second)->get_deltat_at();
131 }
132 else
133 {
134 _system.deltat = (stored_datum->second)->get_deltat_at();
135 }
136 }
137 else
138 {
139 if( stored_datum != std::prev(stored_data.end()) )
140 _system.deltat = (stored_datum->second)->get_deltat_at();
141 else
142 {
143 stored_data_iterator stored_datum_past = stored_datum;
144 stored_datum_past--;
145
146 _system.deltat = (stored_datum_past->second)->get_deltat_at();
147 }
148
149 }
150
151 // Get the time at which we are recovering the solution vectors
152 Real recovery_time = stored_datum->first;
153
154 // Do we not have a solution for this time? Then
155 // there's nothing to do.
156 if (stored_datum == stored_data.end() ||
157 std::abs(recovery_time - time) > TOLERANCE)
158 {
159 //libMesh::out << "No more solutions to recover ! We are at time t = " <<
160 // _system.time << std::endl;
161 return;
162 }
163
164
165 // If we are doing an adjoint solve, we read in the primal solution,
166 // but this overwrites the adjoint solution with zero, so we swap
167 // the last adjoint solution out to prevent this zeroing
168 if(is_adjoint_solve)
169 {
170 // Reading in the primal xdas overwrites the adjoint solution with zero
171 // So swap to retain the adjoint and old adjoint vectors
172 for (auto j : make_range(_system.n_qois()))
173 {
175
176 std::string old_adjoint_solution_name = "_old_adjoint_solution";
177 old_adjoint_solution_name+= std::to_string(j);
178 old_dual_solution_copies[j] = _system.get_vector(old_adjoint_solution_name).clone();
179 }
180
181 // Read in the primal solution stored at the current recovery time from the disk
182 (stored_datum->second)->retrieve_primal_solution();
183
184 // Swap back the copy of adjoint and old adjoint vectors back in place
185 for (auto j : make_range(_system.n_qois()))
186 {
188
189 std::string old_adjoint_solution_name = "_old_adjoint_solution";
190 old_adjoint_solution_name+= std::to_string(j);
191 (_system.get_vector(old_adjoint_solution_name)).swap(*old_dual_solution_copies[j]);
192 }
193 }
194 else
195 {
196 // // If we are not in the adjoint loop, we could be in the primal loop again having solved
197 // // only the primal problem, or in a primal postprocessing stage to evaluate a QoI for example.
198 // // If we can find an adjoint solution file, read that in, else read in the primal file
199 if(dynamic_cast<FileHistoryData &>(*(stored_datum->second)).get_adjoint_filename().empty())
200 (stored_datum->second)->retrieve_primal_solution();
201 else
202 (stored_datum->second)->retrieve_adjoint_solution();
203 }
204
205 // We need to call update to put system in a consistent state
206 // with the solution that was read in
207 _system.update();
208
209}
Real deltat
For time-dependent problems, this is the amount delta t to advance the solution in time.
virtual std::unique_ptr< NumericVector< T > > clone() const =0
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
Definition system.C:1232
const NumericVector< Number > & get_vector(std::string_view vec_name) const
Definition system.C:931
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176

References _system, libMesh::NumericVector< T >::clone(), libMesh::DifferentiableSystem::deltat, dual_solution_copies, libMesh::SolutionHistory::find_stored_entry(), libMesh::FileHistoryData::get_adjoint_filename(), libMesh::System::get_adjoint_solution(), libMesh::System::get_vector(), libMesh::make_range(), libMesh::System::n_qois(), old_dual_solution_copies, libMesh::Real, libMesh::SolutionHistory::stored_data, libMesh::SolutionHistory::stored_datum, libMesh::TOLERANCE, and libMesh::System::update().

◆ set_overwrite_previously_stored()

void libMesh::SolutionHistory::set_overwrite_previously_stored ( bool  val)
inlineinherited

Turn on overwrite_previously_stored to overwrite any already-saved data encountered during subsequent store() calls.

Definition at line 80 of file solution_history.h.

References libMesh::SolutionHistory::overwrite_previously_stored.

◆ store()

void libMesh::FileSolutionHistory::store ( bool  is_adjoint_solve,
Real  time 
)
overridevirtual

Virtual function store which we will be overriding to store timesteps.

Implements libMesh::SolutionHistory.

Definition at line 55 of file file_solution_history.C.

56{
57 // This will map the stored_datum iterator to the current time
58 this->find_stored_entry(time, true);
59
60 // In an empty history we create the first entry
61 if (stored_data.begin() == stored_data.end())
62 {
63 stored_data[time] = std::make_unique<FileHistoryData>(_system);
64 stored_datum = stored_data.begin();
65 }
66
67 // If we're past the end we can create a new entry
68 if (time - stored_datum->first > TOLERANCE )
69 {
70#ifndef NDEBUG
73#endif
74 stored_data[time] = std::make_unique<FileHistoryData>(_system);
77 }
78
79 // If we're before the beginning we can create a new entry
80 else if (stored_datum->first - time > TOLERANCE)
81 {
83 stored_data[time] = std::make_unique<FileHistoryData>(_system);
84 stored_datum = stored_data.begin();
85 }
86
87 // We don't support inserting entries elsewhere
88 libmesh_assert(std::abs(stored_datum->first - time) < TOLERANCE);
89
90 // If we are in the primal loop, either reuse an existing timestamp if a write has been done for
91 // this time earlier. Else, we are at a new time and need to make a new entry in the timeTotimestamp map.
92 if(!is_adjoint_solve)
93 {
94 // First we handle the case of the initial data, this is the only case in which
95 // stored_data will have size one
96 if(stored_data.size() == 1)
97 {
98 (stored_datum->second)->store_initial_solution();
99 }
100 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
101 {
102 (stored_datum->second)->store_primal_solution(stored_datum);
103 }
104 else
105 {
106 (stored_datum->second)->rewrite_stored_solution();
107 }
108 }
109 else // We are in the adjoint time stepping loop
110 {
111 (stored_datum->second)->store_adjoint_solution();
112 }
113
114}

References _system, libMesh::SolutionHistory::find_stored_entry(), libMesh::libmesh_assert(), libMesh::SolutionHistory::stored_data, libMesh::SolutionHistory::stored_datum, and libMesh::TOLERANCE.

Member Data Documentation

◆ _system

DifferentiableSystem& libMesh::FileSolutionHistory::_system
private

Definition at line 79 of file file_solution_history.h.

Referenced by clone(), FileSolutionHistory(), retrieve(), and store().

◆ dual_solution_copies

std::vector< std::unique_ptr<NumericVector<Number> > > libMesh::FileSolutionHistory::dual_solution_copies
private

A vector of pointers to adjoint and old adjoint solutions at the last time step.

These are used to prevent the zeroing of the adjoint and old adjoint by es::read.

Definition at line 85 of file file_solution_history.h.

Referenced by FileSolutionHistory(), and retrieve().

◆ old_dual_solution_copies

std::vector< std::unique_ptr<NumericVector<Number> > > libMesh::FileSolutionHistory::old_dual_solution_copies
private

Definition at line 86 of file file_solution_history.h.

Referenced by FileSolutionHistory(), and retrieve().

◆ overwrite_previously_stored

bool libMesh::SolutionHistory::overwrite_previously_stored
protectedinherited

◆ stored_data

map_type libMesh::SolutionHistory::stored_data
protectedinherited

◆ stored_datum

stored_data_iterator libMesh::SolutionHistory::stored_datum
protectedinherited

The documentation for this class was generated from the following files: