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

Generated on Tue Aug 4 16:10:21 2009 for Chaste by  doxygen 1.5.5