CryptSimulation2d.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
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 "CryptSimulation2d.hpp"
00030 #include "WntConcentration.hpp"
00031 #include "IngeWntSwatCellCycleModel.hpp"
00032 
00033 c_vector<double, 2> CryptSimulation2d::CalculateDividingCellCentreLocations(TissueCell* pParentCell)
00034 {
00035     double separation = CancerParameters::Instance()->GetDivisionSeparation();
00036     c_vector<double, 2> parent_coords = mpStaticCastTissue->GetLocationOfCellCentre(pParentCell);
00037     c_vector<double, 2> daughter_coords;
00038 
00039     // Pick a random direction and move the parent cell backwards by 0.5*sep in that
00040     // direction and return the position of the daughter cell (0.5*sep forwards in the
00041     // random vector direction
00042 
00043     // Make a random direction vector of the required length
00044     c_vector<double, 2> random_vector;
00045 
00046     double random_angle = RandomNumberGenerator::Instance()->ranf();
00047     random_angle *= 2.0*M_PI;
00048 
00049     random_vector(0) = 0.5*separation*cos(random_angle);
00050     random_vector(1) = 0.5*separation*sin(random_angle);
00051 
00052     c_vector<double, 2> proposed_new_parent_coords = parent_coords - random_vector;
00053     c_vector<double, 2> proposed_new_daughter_coords = parent_coords + random_vector;
00054 
00055     if (   (proposed_new_parent_coords(1) >= 0.0)
00056         && (proposed_new_daughter_coords(1) >= 0.0))
00057     {
00058         // We are not too close to the bottom of the tissue
00059         // move parent
00060         parent_coords = proposed_new_parent_coords;
00061         daughter_coords = proposed_new_daughter_coords;
00062     }
00063     else
00064     {
00065         proposed_new_daughter_coords = parent_coords+2.0*random_vector;
00066         while (proposed_new_daughter_coords(1) < 0.0)
00067         {
00068             random_angle = RandomNumberGenerator::Instance()->ranf();
00069             random_angle *= 2.0*M_PI;
00070 
00071             random_vector(0) = separation*cos(random_angle);
00072             random_vector(1) = separation*sin(random_angle);
00073             proposed_new_daughter_coords = parent_coords+random_vector;
00074         }
00075         daughter_coords = proposed_new_daughter_coords;
00076     }
00077 
00078     assert(daughter_coords(1)>=0.0); // to make sure dividing cells stay in the tissue
00079     assert(parent_coords(1)>=0.0);   // to make sure dividing cells stay in the tissue
00080 
00081     // Set the parent to use this location
00082     ChastePoint<2> parent_coords_point(parent_coords);
00083 
00084     unsigned node_index = mpStaticCastTissue->GetLocationIndexUsingCell(pParentCell);
00085     mrTissue.SetNode(node_index, parent_coords_point);
00086 
00087     return daughter_coords;
00088 }
00089 
00090 
00091 void CryptSimulation2d::WriteVisualizerSetupFile()
00092 {
00093     *mpSetupFile << "MeshWidth\t" << mpStaticCastTissue->rGetMesh().GetWidth(0u) << "\n";// get furthest distance between nodes in the x-direction
00094 }
00095 
00096 
00097 void CryptSimulation2d::SetupWriteBetaCatenin()
00098 {
00099     OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
00100     mBetaCatResultsFile = output_file_handler.OpenOutputFile("results.vizbetacatenin");
00101     *mpSetupFile << "BetaCatenin\n";
00102 }
00103 
00104 
00105 void CryptSimulation2d::WriteBetaCatenin(double time)
00106 {
00107     *mBetaCatResultsFile <<  time << "\t";
00108 
00109     unsigned global_index;
00110     double x;
00111     double y;
00112     double b_cat_membrane;
00113     double b_cat_cytoplasm;
00114     double b_cat_nuclear;
00115 
00116     for (AbstractTissue<2>::Iterator cell_iter = mrTissue.Begin();
00117          cell_iter != mrTissue.End();
00118          ++cell_iter)
00119     {
00120         global_index = mpStaticCastTissue->GetLocationIndexUsingCell(&(*cell_iter));
00121         x = mpStaticCastTissue->GetLocationOfCellCentre(&(*cell_iter))[0];
00122         y = mpStaticCastTissue->GetLocationOfCellCentre(&(*cell_iter))[1];
00123 
00124         // If writing beta-catenin, the model has to be an IngeWntSwatCellCycleModel
00125         IngeWntSwatCellCycleModel* p_model = static_cast<IngeWntSwatCellCycleModel*>(cell_iter->GetCellCycleModel());
00126 
00127         b_cat_membrane = p_model->GetMembraneBoundBetaCateninLevel();
00128         b_cat_cytoplasm = p_model->GetCytoplasmicBetaCateninLevel();
00129         b_cat_nuclear = p_model->GetNuclearBetaCateninLevel();
00130 
00131         *mBetaCatResultsFile << global_index << " " << x << " " << y << " " << b_cat_membrane << " " << b_cat_cytoplasm << " " << b_cat_nuclear << " ";
00132     }
00133 
00134     *mBetaCatResultsFile << "\n";
00135 }
00136 
00137 
00138 void CryptSimulation2d::SetupSolve()
00139 {
00140     if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00141         && (dynamic_cast<IngeWntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00142     {
00143         SetupWriteBetaCatenin();
00144         double current_time = SimulationTime::Instance()->GetTime();
00145         WriteBetaCatenin(current_time);
00146     }
00147 }
00148 
00149 
00150 void CryptSimulation2d::PostSolve()
00151 {
00152     SimulationTime *p_time = SimulationTime::Instance();
00153 
00154     if ((p_time->GetTimeStepsElapsed()+1)%mSamplingTimestepMultiple==0)
00155     {
00156         if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00157             && (dynamic_cast<IngeWntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00158         {
00159             double time_next_step = p_time->GetTime() + p_time->GetTimeStep();
00160             WriteBetaCatenin(time_next_step);
00161         }
00162     }
00163 }
00164 
00165 
00166 void CryptSimulation2d::AfterSolve()
00167 {
00168     if (   (mrTissue.Begin() != mrTissue.End()) // there are any cells
00169         && (dynamic_cast<IngeWntSwatCellCycleModel*>(mrTissue.Begin()->GetCellCycleModel())) ) // assume all the cells are the same
00170     {
00171         mBetaCatResultsFile->close();
00172     }
00173 
00174     TissueSimulation<2>::AfterSolve();
00175 }
00176 
00177 
00178 CryptSimulation2d::CryptSimulation2d(AbstractTissue<2>& rTissue,
00179                   std::vector<AbstractForce<2>*> forceCollection,
00180                   bool deleteTissueAndForceCollection,
00181                   bool initialiseCells)
00182     : TissueSimulation<2>(rTissue,
00183                           forceCollection,
00184                           deleteTissueAndForceCollection,
00185                           initialiseCells),
00186       mUseJiggledBottomCells(false)
00187 {
00188     mpStaticCastTissue = static_cast<MeshBasedTissueWithGhostNodes<2>*>(&mrTissue);
00189 }
00190 
00191 
00192 void CryptSimulation2d::UseJiggledBottomCells()
00193 {
00194     mUseJiggledBottomCells = true;
00195 }
00196 
00197 void CryptSimulation2d::ApplyTissueBoundaryConditions(const std::vector< c_vector<double, 2> >& rOldLocations)
00198 {
00199     bool is_wnt_included = WntConcentration::Instance()->IsWntSetUp();
00200     if (!is_wnt_included)
00201     {
00202         WntConcentration::Destroy();
00203     }
00204 
00205     // Iterate over all nodes associated with real cells to update their positions
00206     // according to any tissue boundary conditions
00207     for (AbstractTissue<2>::Iterator cell_iter = mrTissue.Begin();
00208          cell_iter != mrTissue.End();
00209          ++cell_iter)
00210     {
00211         // Get index of node associated with cell
00212         unsigned node_index = mpStaticCastTissue->GetLocationIndexUsingCell(&(*cell_iter));
00213 
00214         // Get pointer to this node
00215         Node<2>* p_node = mpStaticCastTissue->GetNodeCorrespondingToCell(&(*cell_iter));
00216 
00217         if (!is_wnt_included)
00218         {
00223             if (cell_iter->GetCellType()==STEM)
00224             {
00225                 // Get old node location
00226                 c_vector<double, 2> old_node_location = rOldLocations[node_index];
00227 
00228                 // Return node to old location
00229                 p_node->rGetModifiableLocation()[0] = old_node_location[0];
00230                 p_node->rGetModifiableLocation()[1] = old_node_location[1];
00231             }
00232         }
00233 
00234         // Any cell that has moved below the bottom of the crypt must be moved back up
00235         if (p_node->rGetLocation()[1] < 0.0)
00236         {
00237             p_node->rGetModifiableLocation()[1] = 0.0;
00238             if (mUseJiggledBottomCells)
00239             {
00240                /*
00241                 * Here we give the cell a push upwards so that it doesn't
00242                 * get stuck on the bottom of the crypt (as per #422).
00243                 *
00244                 * Note that all stem cells may get moved to the same height, so
00245                 * we use a random perturbation to help ensure we are not simply
00246                 * faced with the same problem at a different height!
00247                 */
00248                 p_node->rGetModifiableLocation()[1] = 0.05*mpRandomGenerator->ranf();
00249             }
00250         }
00251         assert(p_node->rGetLocation()[1] >= 0.0);
00252     }
00253 }

Generated on Wed Mar 18 12:51:50 2009 for Chaste by  doxygen 1.5.5