$extrastylesheet
memory_solution_history.C
Go to the documentation of this file.
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