00001 /* 00002 00003 Copyright (C) University of Oxford, 2005-2010 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 "AbstractOdeBasedCellCycleModel.hpp" 00030 00031 #include <iostream> 00032 #include <cassert> 00033 00034 #include "Exception.hpp" 00035 00036 AbstractOdeBasedCellCycleModel::AbstractOdeBasedCellCycleModel(double lastTime, 00037 boost::shared_ptr<AbstractCellCycleModelOdeSolver> pOdeSolver) 00038 : CellCycleModelOdeHandler(lastTime, pOdeSolver), 00039 mDivideTime(lastTime), 00040 mFinishedRunningOdes(false), 00041 mG2PhaseStartTime(DBL_MAX) 00042 { 00043 AbstractCellCycleModel::SetBirthTime(lastTime); 00044 } 00045 00046 AbstractOdeBasedCellCycleModel::~AbstractOdeBasedCellCycleModel() 00047 { 00048 } 00049 00050 void AbstractOdeBasedCellCycleModel::SetBirthTime(double birthTime) 00051 { 00052 AbstractCellCycleModel::SetBirthTime(birthTime); 00053 mLastTime = birthTime; 00054 mDivideTime = birthTime; 00055 } 00056 00057 std::vector<double> AbstractOdeBasedCellCycleModel::GetProteinConcentrations() const 00058 { 00059 assert(mpOdeSystem != NULL); 00060 return mpOdeSystem->rGetStateVariables(); 00061 } 00062 00063 void AbstractOdeBasedCellCycleModel::SetProteinConcentrationsForTestsOnly(double lastTime, std::vector<double> proteinConcentrations) 00064 { 00065 assert(mpOdeSystem != NULL); 00066 assert(proteinConcentrations.size()==mpOdeSystem->rGetStateVariables().size()); 00067 mLastTime = lastTime; 00068 mpOdeSystem->SetStateVariables(proteinConcentrations); 00069 } 00070 00071 void AbstractOdeBasedCellCycleModel::UpdateCellCyclePhase() 00072 { 00073 assert(mpOdeSystem != NULL); 00074 00075 double current_time = SimulationTime::Instance()->GetTime(); 00076 00077 // Update the phase from M to G1 when necessary 00078 if (mCurrentCellCyclePhase == M_PHASE) 00079 { 00080 double m_duration = GetMDuration(); 00081 if (GetAge() >= m_duration) 00082 { 00083 mCurrentCellCyclePhase = G_ONE_PHASE; 00084 mLastTime = m_duration + mBirthTime; 00085 } 00086 else 00087 { 00088 // Still dividing; don't run ODEs 00089 return; 00090 } 00091 } 00092 00093 if (current_time > mLastTime) 00094 { 00095 if (!mFinishedRunningOdes) 00096 { 00097 // Update whether a stopping event has occurred 00098 mFinishedRunningOdes = SolveOdeToTime(current_time); 00099 00100 // Check no concentrations have gone negative 00101 for (unsigned i=0; i<mpOdeSystem->GetNumberOfStateVariables(); i++) 00102 { 00103 if (mpOdeSystem->rGetStateVariables()[i] < -DBL_EPSILON) 00104 { 00105 #define COVERAGE_IGNORE 00106 std::cout << "Protein["<< i <<"] = "<< mpOdeSystem->rGetStateVariables()[i] << "\n"; 00107 EXCEPTION("A protein concentration has gone negative\nChaste predicts that the CellCycleModel numerical method is probably unstable."); 00108 #undef COVERAGE_IGNORE 00109 } 00110 } 00111 00112 if (mFinishedRunningOdes) 00113 { 00114 // Update durations of each phase 00115 mG1Duration = GetOdeStopTime() - mBirthTime - GetMDuration(); 00116 mG2PhaseStartTime = GetOdeStopTime() + GetSDuration(); 00117 mDivideTime = mG2PhaseStartTime + GetG2Duration(); 00118 00119 // Update phase 00120 if (current_time >= mG2PhaseStartTime) 00121 { 00122 mCurrentCellCyclePhase = G_TWO_PHASE; 00123 } 00124 else 00125 { 00126 mCurrentCellCyclePhase = S_PHASE; 00127 } 00128 } 00129 } 00130 else 00131 { 00132 // ODE model finished, just increasing time until division... 00133 if (current_time >= mG2PhaseStartTime) 00134 { 00135 mCurrentCellCyclePhase = G_TWO_PHASE; 00136 } 00137 } 00138 } 00139 } 00140 00141 void AbstractOdeBasedCellCycleModel::ResetForDivision() 00142 { 00143 assert(mFinishedRunningOdes); 00144 AbstractCellCycleModel::ResetForDivision(); 00145 mBirthTime = mDivideTime; 00146 mLastTime = mDivideTime; 00147 mFinishedRunningOdes = false; 00148 mG1Duration = DBL_MAX; 00149 mDivideTime = DBL_MAX; 00150 } 00151 00152 double AbstractOdeBasedCellCycleModel::GetOdeStopTime() 00153 { 00154 double stop_time = DOUBLE_UNSET; 00155 if (mpOdeSolver->StoppingEventOccurred()) 00156 { 00157 stop_time = mpOdeSolver->GetStoppingTime(); 00158 } 00159 return stop_time; 00160 } 00161 00162 void AbstractOdeBasedCellCycleModel::SetFinishedRunningOdes(bool finishedRunningOdes) 00163 { 00164 mFinishedRunningOdes = finishedRunningOdes; 00165 } 00166 00167 void AbstractOdeBasedCellCycleModel::SetDivideTime(double divideTime) 00168 { 00169 mDivideTime = divideTime; 00170 } 00171 00172 void AbstractOdeBasedCellCycleModel::SetG2PhaseStartTime(double g2PhaseStartTime) 00173 { 00174 mG2PhaseStartTime = g2PhaseStartTime; 00175 }