$extrastylesheet
00001 // Function definitions for MemorySolutionHistory 00002 00003 // Local includes 00004 #include "libmesh/memory_solution_history.h" 00005 00006 #include <cmath> 00007 00008 namespace libMesh 00009 { 00010 // The Destructor 00011 MemorySolutionHistory::~MemorySolutionHistory () 00012 { 00013 stored_solutions_iterator stored_sols_it = stored_solutions.begin(); 00014 const stored_solutions_iterator stored_sols_end = stored_solutions.end(); 00015 00016 for(; stored_sols_it != stored_sols_end; ++stored_sols_it) 00017 { 00018 // The saved vectors at this timestep 00019 std::map<std::string, NumericVector<Number> *> saved_vectors = stored_sols_it->second; 00020 00021 std::map<std::string, NumericVector<Number> *>::iterator vec = saved_vectors.begin(); 00022 std::map<std::string, NumericVector<Number> *>::iterator vec_end = saved_vectors.end(); 00023 00024 // Loop over all the saved vectors 00025 for (; vec != vec_end; ++vec) 00026 { 00027 // Delete this saved vector 00028 delete vec->second; 00029 } 00030 } 00031 } 00032 00033 // This function finds, if it can, the entry where we're supposed to 00034 // be storing data 00035 void MemorySolutionHistory::find_stored_entry() 00036 { 00037 if (stored_solutions.begin() == stored_solutions.end()) 00038 return; 00039 00040 libmesh_assert (stored_sols != stored_solutions.end()); 00041 00042 if (std::abs(stored_sols->first - _system.time) < TOLERANCE) 00043 return; 00044 00045 // If we're not at the front, check the previous entry 00046 if (stored_sols != stored_solutions.begin()) 00047 { 00048 stored_solutions_iterator test_it = stored_sols; 00049 if (std::abs((--test_it)->first - _system.time) < TOLERANCE) 00050 { 00051 --stored_sols; 00052 return; 00053 } 00054 } 00055 00056 // If we're not at the end, check the subsequent entry 00057 stored_solutions_iterator test_it = stored_sols; 00058 if ((++test_it) != stored_solutions.end()) 00059 { 00060 if (std::abs(test_it->first - _system.time) < TOLERANCE) 00061 { 00062 ++stored_sols; 00063 return; 00064 } 00065 } 00066 } 00067 00068 // This functions saves all the 'projection-worthy' system vectors for 00069 // future use 00070 void MemorySolutionHistory::store() 00071 { 00072 this->find_stored_entry(); 00073 00074 // In an empty history we create the first entry 00075 if (stored_solutions.begin() == stored_solutions.end()) 00076 { 00077 stored_solutions.push_back 00078 (std::make_pair(_system.time, 00079 std::map<std::string, NumericVector<Number> *>())); 00080 stored_sols = stored_solutions.begin(); 00081 } 00082 00083 // If we're past the end we can create a new entry 00084 if (_system.time - stored_sols->first > TOLERANCE ) 00085 { 00086 #ifndef NDEBUG 00087 ++stored_sols; 00088 libmesh_assert (stored_sols == stored_solutions.end()); 00089 #endif 00090 stored_solutions.push_back 00091 (std::make_pair(_system.time, 00092 std::map<std::string, NumericVector<Number> *>())); 00093 stored_sols = stored_solutions.end(); 00094 --stored_sols; 00095 } 00096 00097 // If we're before the beginning we can create a new entry 00098 else if (stored_sols->first - _system.time > TOLERANCE) 00099 { 00100 libmesh_assert (stored_sols == stored_solutions.begin()); 00101 stored_solutions.push_front 00102 (std::make_pair(_system.time, 00103 std::map<std::string, NumericVector<Number> *>())); 00104 stored_sols = stored_solutions.begin(); 00105 } 00106 00107 // We don't support inserting entries elsewhere 00108 libmesh_assert(std::abs(stored_sols->first - _system.time) < TOLERANCE); 00109 00110 // Map of stored vectors for this solution step 00111 std::map<std::string, NumericVector<Number> *>& saved_vectors = stored_sols->second; 00112 00113 // Loop over all the system vectors 00114 for (System::vectors_iterator vec = _system.vectors_begin(); vec != _system.vectors_end(); ++vec) 00115 { 00116 // The name of this vector 00117 const std::string& vec_name = vec->first; 00118 00119 // If we haven't seen this vector before or if we have and 00120 // want to overwrite it 00121 if ((overwrite_previously_stored || 00122 !saved_vectors.count(vec_name)) && 00123 // and if we think it's worth preserving 00124 _system.vector_preservation(vec_name)) 00125 { 00126 // Then we save it. 00127 saved_vectors[vec_name] = vec->second->clone().release(); 00128 } 00129 } 00130 00131 // Of course, we will usually save the actual solution 00132 std::string _solution("_solution"); 00133 if ((overwrite_previously_stored || 00134 !saved_vectors.count(_solution)) && 00135 // and if we think it's worth preserving 00136 _system.project_solution_on_reinit()) 00137 saved_vectors[_solution] = _system.solution->clone().release(); 00138 } 00139 00140 void MemorySolutionHistory::retrieve() 00141 { 00142 this->find_stored_entry(); 00143 00144 // Get the time at which we are recovering the solution vectors 00145 Real recovery_time = stored_sols->first; 00146 00147 // Print out what time we are recovering vectors at 00148 // libMesh::out << "Recovering solution vectors at time: " << 00149 // recovery_time << std::endl; 00150 00151 // Do we not have a solution for this time? Then 00152 // there's nothing to do. 00153 if(stored_sols == stored_solutions.end() || 00154 std::abs(recovery_time - _system.time) > TOLERANCE) 00155 { 00156 //libMesh::out << "No more solutions to recover ! We are at time t = " << 00157 // _system.time << std::endl; 00158 return; 00159 } 00160 00161 // Get the saved vectors at this timestep 00162 std::map<std::string, NumericVector<Number> *>& saved_vectors = stored_sols->second; 00163 00164 std::map<std::string, NumericVector<Number> *>::iterator vec = saved_vectors.begin(); 00165 std::map<std::string, NumericVector<Number> *>::iterator vec_end = saved_vectors.end(); 00166 00167 // Loop over all the saved vectors 00168 for (; vec != vec_end; ++vec) 00169 { 00170 // The name of this vector 00171 const std::string& vec_name = vec->first; 00172 00173 // Get the vec_name entry in the saved vectors map and set the 00174 // current system vec[vec_name] entry to it 00175 if (vec_name != "_solution") 00176 _system.get_vector(vec_name) = *(vec->second); 00177 } 00178 00179 // Of course, we will *always* have to get the actual solution 00180 std::string _solution("_solution"); 00181 *(_system.solution) = *(saved_vectors[_solution]); 00182 } 00183 00184 } 00185 // End namespace libMesh