00001 /* 00002 00003 Copyright (C) University of Oxford, 2005-2011 00004 00005 University of Oxford means the Chancellor, Masters and Scholars of the 00006 University of Oxford, having an administrative office at Wellington 00007 Square, Oxford OX1 2JD, UK. 00008 00009 This file is part of Chaste. 00010 00011 Chaste is free software: you can redistribute it and/or modify it 00012 under the terms of the GNU Lesser General Public License as published 00013 by the Free Software Foundation, either version 2.1 of the License, or 00014 (at your option) any later version. 00015 00016 Chaste is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00018 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00019 License for more details. The offer of Chaste under the terms of the 00020 License is subject to the License being interpreted in accordance with 00021 English Law and subject to any action against the University of Oxford 00022 being under the jurisdiction of the English Courts. 00023 00024 You should have received a copy of the GNU Lesser General Public License 00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>. 00026 00027 */ 00028 00029 #include <cassert> 00030 #include <cmath> 00031 #include "SimulationTime.hpp" 00032 00034 SimulationTime* SimulationTime::mpInstance = NULL; 00035 00037 boost::shared_ptr<TimeStepper> SimulationTime::mpTimeStepper; 00038 00039 SimulationTime* SimulationTime::Instance() 00040 { 00041 if (mpInstance == NULL) 00042 { 00043 mpInstance = new SimulationTime; 00044 mpTimeStepper.reset(); 00045 std::atexit(Destroy); 00046 } 00047 return mpInstance; 00048 } 00049 00050 SimulationTime::SimulationTime() 00051 : 00052 mStartTime(DOUBLE_UNSET) 00053 { 00054 // Make sure there's only one instance - enforces correct serialization 00055 assert(mpInstance == NULL); 00056 } 00057 00058 void SimulationTime::Destroy() 00059 { 00060 if (mpInstance) 00061 { 00062 delete mpInstance; 00063 mpInstance = NULL; 00064 } 00065 } 00066 00067 double SimulationTime::GetTimeStep() const 00068 { 00069 assert(mpTimeStepper); 00070 return mpTimeStepper->GetIdealTimeStep(); 00071 } 00072 00073 void SimulationTime::IncrementTimeOneStep() 00074 { 00075 assert(mpTimeStepper); 00076 mpTimeStepper->AdvanceOneTimeStep(); //This can now throw if the end time has been reached 00077 } 00078 00079 unsigned SimulationTime::GetTimeStepsElapsed() const 00080 { 00081 assert(mpTimeStepper); 00082 return mpTimeStepper->GetTotalTimeStepsTaken(); 00083 } 00084 00085 double SimulationTime::GetTime() const 00086 { 00087 // NOTE: if this assertion fails, it may be because Destroy() wasn't called in the previous test 00088 assert(mStartTime != DOUBLE_UNSET); 00089 //Check if the time stepping has started 00090 if (mpTimeStepper) 00091 { 00092 return mpTimeStepper->GetTime(); 00093 } 00094 //If time stepping hasn't started then we are still at start time 00095 return mStartTime; 00096 } 00097 00098 void SimulationTime::SetStartTime(double startTime) 00099 { 00100 assert(mStartTime == DOUBLE_UNSET); 00101 mStartTime = startTime; 00102 } 00103 00104 void SimulationTime::SetEndTimeAndNumberOfTimeSteps(double endTime, unsigned totalTimeStepsInSimulation) 00105 { 00106 // NOTE: if this assertion fails, it may be because Destroy() wasn't called in the previous test 00107 assert(mStartTime != DOUBLE_UNSET); 00108 assert(!mpTimeStepper); 00109 assert(endTime > mStartTime); 00110 00111 mpTimeStepper.reset(new TimeStepper(mStartTime, endTime, (endTime-mStartTime)/totalTimeStepsInSimulation, true)); 00112 } 00113 00114 void SimulationTime::ResetEndTimeAndNumberOfTimeSteps(const double& rEndTime, const unsigned& rNumberOfTimeStepsInThisRun) 00115 { 00116 // NOTE: if this assertion fails, it may be because Destroy() wasn't called in the previous test 00117 assert(mStartTime != DOUBLE_UNSET); 00118 // NOTE: If this assertion fails, you should be using set rather than reset 00119 assert(mpTimeStepper); 00120 mStartTime = mpTimeStepper->GetTime(); 00121 00122 assert(rEndTime > mStartTime); 00123 00124 // Reset the machinery that works out the time 00125 mpTimeStepper.reset(new TimeStepper(mStartTime, rEndTime, (rEndTime-mStartTime)/rNumberOfTimeStepsInThisRun, true)); 00126 } 00127 00128 bool SimulationTime::IsStartTimeSetUp() const 00129 { 00130 return (mStartTime != DOUBLE_UNSET); 00131 } 00132 00133 bool SimulationTime::IsEndTimeAndNumberOfTimeStepsSetUp() const 00134 { 00135 if(mpTimeStepper) 00136 { 00137 return true; 00138 } 00139 else 00140 { 00141 return false; 00142 } 00143 } 00144 00145 bool SimulationTime::IsFinished() const 00146 { 00147 // assert(mpTimeStepper); 00148 return(mpTimeStepper->IsTimeAtEnd()); 00149 } 00150