00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "MeshBasedCellPopulation.hpp"
00030 #include "CellwiseData.hpp"
00031 #include "TrianglesMeshWriter.hpp"
00032 #include "VtkMeshWriter.hpp"
00033 #include "CellBasedEventHandler.hpp"
00034 #include "ApoptoticCellProperty.hpp"
00035 #include "Cylindrical2dMesh.hpp"
00036
00037 template<unsigned DIM>
00038 MeshBasedCellPopulation<DIM>::MeshBasedCellPopulation(MutableMesh<DIM, DIM>& rMesh,
00039 std::vector<CellPtr>& rCells,
00040 const std::vector<unsigned> locationIndices,
00041 bool deleteMesh,
00042 bool validate)
00043 : AbstractCentreBasedCellPopulation<DIM>(rCells, locationIndices),
00044 mrMesh(rMesh),
00045 mpVoronoiTessellation(NULL),
00046 mDeleteMesh(deleteMesh),
00047 mUseAreaBasedDampingConstant(false),
00048 mAreaBasedDampingConstantParameter(0.1),
00049 mOutputVoronoiData(false),
00050 mOutputCellPopulationVolumes(false),
00051 mWriteVtkAsPoints(false)
00052 {
00053
00054 assert(this->mCells.size() <= mrMesh.GetNumNodes());
00055
00056 this->mCellPopulationContainsMesh = true;
00057
00058 if (validate)
00059 {
00060 Validate();
00061 }
00062 }
00063
00064 template<unsigned DIM>
00065 MeshBasedCellPopulation<DIM>::MeshBasedCellPopulation(MutableMesh<DIM, DIM>& rMesh)
00066 : mrMesh(rMesh)
00067 {
00068 this->mCellPopulationContainsMesh = true;
00069 mpVoronoiTessellation = NULL;
00070 mDeleteMesh = true;
00071 }
00072
00073 template<unsigned DIM>
00074 MeshBasedCellPopulation<DIM>::~MeshBasedCellPopulation()
00075 {
00076 delete mpVoronoiTessellation;
00077
00078 if (mDeleteMesh)
00079 {
00080 delete &mrMesh;
00081 }
00082 }
00083
00084 template<unsigned DIM>
00085 bool MeshBasedCellPopulation<DIM>::UseAreaBasedDampingConstant()
00086 {
00087 return mUseAreaBasedDampingConstant;
00088 }
00089
00090 template<unsigned DIM>
00091 void MeshBasedCellPopulation<DIM>::SetAreaBasedDampingConstant(bool useAreaBasedDampingConstant)
00092 {
00093 assert(DIM==2);
00094 mUseAreaBasedDampingConstant = useAreaBasedDampingConstant;
00095 }
00096
00097 template<unsigned DIM>
00098 unsigned MeshBasedCellPopulation<DIM>::AddNode(Node<DIM>* pNewNode)
00099 {
00100 return mrMesh.AddNode(pNewNode);
00101 }
00102
00103 template<unsigned DIM>
00104 void MeshBasedCellPopulation<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00105 {
00106 mrMesh.SetNode(nodeIndex, rNewLocation, false);
00107 }
00108
00109 template<unsigned DIM>
00110 double MeshBasedCellPopulation<DIM>::GetDampingConstant(unsigned nodeIndex)
00111 {
00112 double damping_multiplier = AbstractCentreBasedCellPopulation<DIM>::GetDampingConstant(nodeIndex);
00113
00114 if (mUseAreaBasedDampingConstant)
00115 {
00125 assert(DIM==2);
00126
00127 double rest_length = 1.0;
00128 double d0 = mAreaBasedDampingConstantParameter;
00129
00135 double d1 = 2.0*(1.0 - d0)/(sqrt(3)*rest_length*rest_length);
00136
00137 double area_cell = GetVolumeOfVoronoiElement(nodeIndex);
00138
00144 assert(area_cell < 1000);
00145
00146 damping_multiplier = d0 + area_cell*d1;
00147 }
00148
00149 return damping_multiplier;
00150 }
00151
00152 template<unsigned DIM>
00153 void MeshBasedCellPopulation<DIM>::Validate()
00154 {
00155 std::vector<bool> validated_node = std::vector<bool>(this->GetNumNodes(), false);
00156
00157 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00158 {
00159 unsigned node_index = GetLocationIndexUsingCell(*cell_iter);
00160 validated_node[node_index] = true;
00161 }
00162
00163 for (unsigned i=0; i<validated_node.size(); i++)
00164 {
00165 if (!validated_node[i])
00166 {
00167 std::stringstream ss;
00168 ss << "Node " << i << " does not appear to have a cell associated with it";
00169 EXCEPTION(ss.str());
00170 }
00171 }
00172 }
00173
00174 template<unsigned DIM>
00175 MutableMesh<DIM, DIM>& MeshBasedCellPopulation<DIM>::rGetMesh()
00176 {
00177 return mrMesh;
00178 }
00179
00180 template<unsigned DIM>
00181 const MutableMesh<DIM, DIM>& MeshBasedCellPopulation<DIM>::rGetMesh() const
00182 {
00183 return mrMesh;
00184 }
00185
00186 template<unsigned DIM>
00187 unsigned MeshBasedCellPopulation<DIM>::RemoveDeadCells()
00188 {
00189 unsigned num_removed = 0;
00190 for (std::list<CellPtr>::iterator it = this->mCells.begin();
00191 it != this->mCells.end();
00192 ++it)
00193 {
00194 if ((*it)->IsDead())
00195 {
00196
00197 std::vector<const std::pair<CellPtr,CellPtr>*> pairs_to_remove;
00198 for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = mMarkedSprings.begin();
00199 it1 != mMarkedSprings.end();
00200 ++it1)
00201 {
00202 const std::pair<CellPtr,CellPtr>& r_pair = *it1;
00203
00204 for (unsigned i=0; i<2; i++)
00205 {
00206 CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
00207
00208 if (p_cell == *it)
00209 {
00210
00211 pairs_to_remove.push_back(&r_pair);
00212 break;
00213 }
00214 }
00215 }
00216
00217
00218 for (std::vector<const std::pair<CellPtr,CellPtr>* >::iterator pair_it = pairs_to_remove.begin();
00219 pair_it != pairs_to_remove.end();
00220 ++pair_it)
00221 {
00222 mMarkedSprings.erase(**pair_it);
00223 }
00224
00225
00226 num_removed++;
00227 mrMesh.DeleteNodePriorToReMesh(this->mCellLocationMap[(*it).get()]);
00228
00229
00230 unsigned location_index_of_removed_node = this->mCellLocationMap[(*it).get()];
00231 this->mCellLocationMap.erase((*it).get());
00232 this->mLocationCellMap.erase(location_index_of_removed_node);
00233
00234
00235 it = this->mCells.erase(it);
00236 --it;
00237 }
00238 }
00239
00240 return num_removed;
00241 }
00242
00243
00244 template<unsigned DIM>
00245 void MeshBasedCellPopulation<DIM>::Update(bool hasHadBirthsOrDeaths)
00246 {
00247 NodeMap map(mrMesh.GetNumAllNodes());
00248 mrMesh.ReMesh(map);
00249
00250 if (!map.IsIdentityMap())
00251 {
00252 UpdateGhostNodesAfterReMesh(map);
00253
00254
00255 std::map<Cell*, unsigned> old_map = this->mCellLocationMap;
00256
00257
00258 this->mLocationCellMap.clear();
00259 this->mCellLocationMap.clear();
00260
00261 for (std::list<CellPtr>::iterator it = this->mCells.begin();
00262 it != this->mCells.end();
00263 ++it)
00264 {
00265 unsigned old_node_index = old_map[(*it).get()];
00266
00267
00268 assert(!map.IsDeleted(old_node_index));
00269
00270 unsigned new_node_index = map.GetNewIndex(old_node_index);
00271 this->mLocationCellMap[new_node_index] = *it;
00272 this->mCellLocationMap[(*it).get()] = new_node_index;
00273 }
00274
00275 this->Validate();
00276 }
00277
00278
00279 std::vector<const std::pair<CellPtr,CellPtr>*> springs_to_remove;
00280 for (std::set<std::pair<CellPtr,CellPtr> >::iterator spring_it = mMarkedSprings.begin();
00281 spring_it != mMarkedSprings.end();
00282 ++spring_it)
00283 {
00284 CellPtr p_cell_1 = spring_it->first;
00285 CellPtr p_cell_2 = spring_it->second;
00286 Node<DIM>* p_node_1 = this->GetNodeCorrespondingToCell(p_cell_1);
00287 Node<DIM>* p_node_2 = this->GetNodeCorrespondingToCell(p_cell_2);
00288
00289 bool joined = false;
00290
00291
00292 std::set<unsigned> node2_elements = p_node_2->rGetContainingElementIndices();
00293 for (typename Node<DIM>::ContainingElementIterator elem_iter = p_node_1->ContainingElementsBegin();
00294 elem_iter != p_node_1->ContainingElementsEnd();
00295 ++elem_iter)
00296 {
00297 if (node2_elements.find(*elem_iter) != node2_elements.end())
00298 {
00299 joined = true;
00300 break;
00301 }
00302 }
00303
00304
00305 if (!joined)
00306 {
00307 springs_to_remove.push_back(&(*spring_it));
00308 }
00309 }
00310
00311
00312 for (std::vector<const std::pair<CellPtr,CellPtr>* >::iterator spring_it = springs_to_remove.begin();
00313 spring_it != springs_to_remove.end();
00314 ++spring_it)
00315 {
00316 mMarkedSprings.erase(**spring_it);
00317 }
00318
00319
00320 if (DIM==2 || DIM==3)
00321 {
00322 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::TESSELLATION);
00323 if (mUseAreaBasedDampingConstant || mOutputVoronoiData || mOutputCellPopulationVolumes || this->mOutputCellVolumes)
00324 {
00325 CreateVoronoiTessellation();
00326 }
00327 CellBasedEventHandler::EndEvent(CellBasedEventHandler::TESSELLATION);
00328 }
00329
00330 mrMesh.SetMeshHasChangedSinceLoading();
00331 }
00332
00333 template<unsigned DIM>
00334 Node<DIM>* MeshBasedCellPopulation<DIM>::GetNode(unsigned index)
00335 {
00336 return mrMesh.GetNode(index);
00337 }
00338
00339 template<unsigned DIM>
00340 unsigned MeshBasedCellPopulation<DIM>::GetNumNodes()
00341 {
00342 return mrMesh.GetNumAllNodes();
00343 }
00344
00345 template<unsigned DIM>
00346 void MeshBasedCellPopulation<DIM>::UpdateGhostNodesAfterReMesh(NodeMap& rMap)
00347 {
00348 }
00349
00350 template<unsigned DIM>
00351 CellPtr MeshBasedCellPopulation<DIM>::AddCell(CellPtr pNewCell, const c_vector<double,DIM>& rCellDivisionVector, CellPtr pParentCell)
00352 {
00353 assert(pNewCell);
00354 assert(pParentCell);
00355
00356
00357 CellPtr p_created_cell = AbstractCentreBasedCellPopulation<DIM>::AddCell(pNewCell, rCellDivisionVector, pParentCell);
00358 assert(p_created_cell == pNewCell);
00359
00360
00361 std::pair<CellPtr,CellPtr> cell_pair = CreateCellPair(pParentCell, p_created_cell);
00362 MarkSpring(cell_pair);
00363
00364
00365 return p_created_cell;
00366 }
00367
00369
00371
00372 template<unsigned DIM>
00373 void MeshBasedCellPopulation<DIM>::CreateOutputFiles(const std::string& rDirectory, bool cleanOutputDirectory)
00374 {
00375 AbstractCentreBasedCellPopulation<DIM>::CreateOutputFiles(rDirectory, cleanOutputDirectory);
00376
00377 OutputFileHandler output_file_handler(rDirectory, cleanOutputDirectory);
00378 mpVizElementsFile = output_file_handler.OpenOutputFile("results.vizelements");
00379
00380 if (mOutputVoronoiData)
00381 {
00382 mpVoronoiFile = output_file_handler.OpenOutputFile("voronoi.dat");
00383 }
00384 if (mOutputCellPopulationVolumes)
00385 {
00386 mpCellPopulationVolumesFile = output_file_handler.OpenOutputFile("cellpopulationareas.dat");
00387 }
00388 if (this->mOutputCellVolumes)
00389 {
00390 mpCellVolumesFile = output_file_handler.OpenOutputFile("cellareas.dat");
00391 }
00392 }
00393
00394 template<unsigned DIM>
00395 void MeshBasedCellPopulation<DIM>::CloseOutputFiles()
00396 {
00397 AbstractCentreBasedCellPopulation<DIM>::CloseOutputFiles();
00398
00399 mpVizElementsFile->close();
00400
00401 if (mOutputVoronoiData)
00402 {
00403 mpVoronoiFile->close();
00404 }
00405 if (mOutputCellPopulationVolumes)
00406 {
00407 mpCellPopulationVolumesFile->close();
00408 }
00409 if (this->mOutputCellVolumes)
00410 {
00411 mpCellVolumesFile->close();
00412 }
00413 }
00414
00415 template<unsigned DIM>
00416 void MeshBasedCellPopulation<DIM>::WriteResultsToFiles()
00417 {
00418 AbstractCentreBasedCellPopulation<DIM>::WriteResultsToFiles();
00419
00420
00421 *mpVizElementsFile << SimulationTime::Instance()->GetTime() << "\t";
00422
00423 for (typename MutableMesh<DIM,DIM>::ElementIterator elem_iter = mrMesh.GetElementIteratorBegin();
00424 elem_iter != mrMesh.GetElementIteratorEnd();
00425 ++elem_iter)
00426 {
00427 bool element_contains_dead_cells_or_deleted_nodes = false;
00428
00429
00430 for (unsigned i=0; i<DIM+1; i++)
00431 {
00432 unsigned node_index = elem_iter->GetNodeGlobalIndex(i);
00433
00434 if (this->GetNode(node_index)->IsDeleted())
00435 {
00436 element_contains_dead_cells_or_deleted_nodes = true;
00437 break;
00438 }
00439 else if (this->mLocationCellMap[node_index])
00440 {
00441 if (this->mLocationCellMap[node_index]->IsDead())
00442 {
00443 element_contains_dead_cells_or_deleted_nodes = true;
00444 break;
00445 }
00446 }
00447 }
00448 if (!element_contains_dead_cells_or_deleted_nodes)
00449 {
00450 for (unsigned i=0; i<DIM+1; i++)
00451 {
00452 *mpVizElementsFile << elem_iter->GetNodeGlobalIndex(i) << " ";
00453 }
00454 }
00455 }
00456 *mpVizElementsFile << "\n";
00457
00458 if (mpVoronoiTessellation != NULL)
00459 {
00460 if (mOutputVoronoiData)
00461 {
00462 WriteVoronoiResultsToFile();
00463 }
00464 if (mOutputCellPopulationVolumes)
00465 {
00466 WriteCellPopulationVolumeResultsToFile();
00467 }
00468 if (this->mOutputCellVolumes)
00469 {
00470 WriteCellVolumeResultsToFile();
00471 }
00472 }
00473 }
00474
00475 template<unsigned DIM>
00476 void MeshBasedCellPopulation<DIM>::WriteVtkResultsToFile()
00477 {
00478 #ifdef CHASTE_VTK
00479
00480 std::stringstream time;
00481 time << SimulationTime::Instance()->GetTimeStepsElapsed();
00482
00483 unsigned num_points = GetNumNodes();
00484 if (!mWriteVtkAsPoints && (mpVoronoiTessellation != NULL))
00485 {
00486 num_points = mpVoronoiTessellation->GetNumElements();
00487 }
00488
00489 std::vector<double> cell_types(num_points);
00490 std::vector<double> cell_ancestors(num_points);
00491 std::vector<double> cell_mutation_states(num_points);
00492 std::vector<double> cell_ages(num_points);
00493 std::vector<double> cell_cycle_phases(num_points);
00494 std::vector<std::vector<double> > cellwise_data;
00495
00496 if (CellwiseData<DIM>::Instance()->IsSetUp())
00497 {
00498 CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00499 for (unsigned var=0; var<p_data->GetNumVariables(); var++)
00500 {
00501 std::vector<double> cellwise_data_var(num_points);
00502 cellwise_data.push_back(cellwise_data_var);
00503 }
00504 }
00505
00506 if (mWriteVtkAsPoints)
00507 {
00508 VtkMeshWriter<DIM, DIM> mesh_writer(this->mDirPath, "results_"+time.str(), false);
00509
00510
00511 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00512 cell_iter != this->End();
00513 ++cell_iter)
00514 {
00515
00516 unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
00517
00518
00519 AbstractCellCycleModel* p_model = cell_iter->GetCellCycleModel();
00520
00521 if (this->mOutputCellAncestors)
00522 {
00523 double ancestor_index = (cell_iter->GetAncestor() == UNSIGNED_UNSET) ? (-1.0) : (double)cell_iter->GetAncestor();
00524 cell_ancestors[node_index] = ancestor_index;
00525 }
00526 if (this->mOutputCellProliferativeTypes)
00527 {
00528 cell_types[node_index] = p_model->GetCellProliferativeType();
00529 }
00530 if (this->mOutputCellMutationStates)
00531 {
00532 cell_mutation_states[node_index] = cell_iter->GetMutationState()->GetColour();
00533 }
00534 if (this->mOutputCellAges)
00535 {
00536 cell_ages[node_index] = cell_iter->GetAge();
00537 }
00538 if (this->mOutputCellCyclePhases)
00539 {
00540 cell_cycle_phases[node_index] = p_model->GetCurrentCellCyclePhase();
00541 }
00542 if (CellwiseData<DIM>::Instance()->IsSetUp())
00543 {
00544 CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00545 for (unsigned var=0; var<p_data->GetNumVariables(); var++)
00546 {
00547 cellwise_data[var][node_index] = p_data->GetValue(*cell_iter, var);
00548 }
00549 }
00550 }
00551
00552 if (this->mOutputCellProliferativeTypes)
00553 {
00554 mesh_writer.AddPointData("Cell types", cell_types);
00555 }
00556 if (this->mOutputCellAncestors)
00557 {
00558 mesh_writer.AddPointData("Ancestors", cell_ancestors);
00559 }
00560 if (this->mOutputCellMutationStates)
00561 {
00562 mesh_writer.AddPointData("Mutation states", cell_mutation_states);
00563 }
00564 if (this->mOutputCellAges)
00565 {
00566 mesh_writer.AddPointData("Ages", cell_ages);
00567 }
00568 if (this->mOutputCellCyclePhases)
00569 {
00570 mesh_writer.AddPointData("Cycle phases", cell_cycle_phases);
00571 }
00572 if (CellwiseData<DIM>::Instance()->IsSetUp())
00573 {
00574 for (unsigned var=0; var<cellwise_data.size(); var++)
00575 {
00576 std::stringstream data_name;
00577 data_name << "Cellwise data " << var;
00578 std::vector<double> cellwise_data_var = cellwise_data[var];
00579 mesh_writer.AddPointData(data_name.str(), cellwise_data_var);
00580 }
00581 }
00582
00583 {
00584
00585 std::vector<Node<DIM>* > nodes;
00586 for (unsigned index=0; index<mrMesh.GetNumNodes(); index++)
00587 {
00588 Node<DIM>* p_node = mrMesh.GetNode(index);
00589 nodes.push_back(p_node);
00590 }
00591 TetrahedralMesh<DIM,DIM> mesh;
00592 mesh.ConstructNodesWithoutMesh(nodes);
00593 mesh_writer.WriteFilesUsingMesh(mesh);
00594 }
00595
00596 *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
00597 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00598 *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
00599 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00600 *(this->mpVtkMetaFile) << ".vtu\"/>\n";
00601 }
00602 else if (mpVoronoiTessellation != NULL)
00603 {
00604 VertexMeshWriter<DIM, DIM> mesh_writer(this->mDirPath, "results", false);
00605 std::vector<double> cell_volumes(num_points);
00606
00607
00608 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
00609 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
00610 ++elem_iter)
00611 {
00612
00613 unsigned elem_index = elem_iter->GetIndex();
00614
00615
00616 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
00617
00618
00619 assert(!this->IsGhostNode(node_index));
00620
00621
00622 CellPtr p_cell = this->mLocationCellMap[node_index];
00623
00624
00625 AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
00626
00627 if (this->mOutputCellAncestors)
00628 {
00629 double ancestor_index = (p_cell->GetAncestor() == UNSIGNED_UNSET) ? (-1.0) : (double)p_cell->GetAncestor();
00630 cell_ancestors[elem_index] = ancestor_index;
00631 }
00632 if (this->mOutputCellProliferativeTypes)
00633 {
00634 cell_types[elem_index] = p_model->GetCellProliferativeType();
00635 }
00636 if (this->mOutputCellMutationStates)
00637 {
00638 cell_mutation_states[elem_index] = p_cell->GetMutationState()->GetColour();
00639 }
00640 if (this->mOutputCellAges)
00641 {
00642 cell_ages[elem_index] = p_cell->GetAge();
00643 }
00644 if (this->mOutputCellCyclePhases)
00645 {
00646 cell_cycle_phases[elem_index] = p_model->GetCurrentCellCyclePhase();
00647 }
00648 if (this->mOutputCellVolumes)
00649 {
00650 cell_volumes[elem_index] = mpVoronoiTessellation->GetVolumeOfElement(elem_index);
00651 }
00652 if (CellwiseData<DIM>::Instance()->IsSetUp())
00653 {
00654 CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00655 for (unsigned var=0; var<p_data->GetNumVariables(); var++)
00656 {
00657 cellwise_data[var][elem_index] = p_data->GetValue(p_cell, var);
00658 }
00659 }
00660 }
00661
00662 if (this->mOutputCellProliferativeTypes)
00663 {
00664 mesh_writer.AddCellData("Cell types", cell_types);
00665 }
00666 if (this->mOutputCellAncestors)
00667 {
00668 mesh_writer.AddCellData("Ancestors", cell_ancestors);
00669 }
00670 if (this->mOutputCellMutationStates)
00671 {
00672 mesh_writer.AddCellData("Mutation states", cell_mutation_states);
00673 }
00674 if (this->mOutputCellAges)
00675 {
00676 mesh_writer.AddCellData("Ages", cell_ages);
00677 }
00678 if (this->mOutputCellCyclePhases)
00679 {
00680 mesh_writer.AddCellData("Cycle phases", cell_cycle_phases);
00681 }
00682 if (this->mOutputCellVolumes)
00683 {
00684 mesh_writer.AddCellData("Cell volumes", cell_volumes);
00685 }
00686 if (CellwiseData<DIM>::Instance()->IsSetUp())
00687 {
00688 for (unsigned var=0; var<cellwise_data.size(); var++)
00689 {
00690 std::stringstream data_name;
00691 data_name << "Cellwise data " << var;
00692 std::vector<double> cellwise_data_var = cellwise_data[var];
00693 mesh_writer.AddCellData(data_name.str(), cellwise_data_var);
00694 }
00695 }
00696
00697 mesh_writer.WriteVtkUsingMesh(*mpVoronoiTessellation, time.str());
00698 *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
00699 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00700 *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
00701 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00702 *(this->mpVtkMetaFile) << ".vtu\"/>\n";
00703 }
00704 #endif //CHASTE_VTK
00705 }
00706
00707 template<unsigned DIM>
00708 void MeshBasedCellPopulation<DIM>::WriteVoronoiResultsToFile()
00709 {
00710 assert(DIM==2 || DIM==3);
00711
00712
00713 *mpVoronoiFile << SimulationTime::Instance()->GetTime() << " ";
00714
00715
00716 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
00717 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
00718 ++elem_iter)
00719 {
00720
00721 unsigned elem_index = elem_iter->GetIndex();
00722
00723
00724 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
00725
00726
00727 *mpVoronoiFile << node_index << " ";
00728 c_vector<double, DIM> node_location = this->GetNode(node_index)->rGetLocation();
00729 for (unsigned i=0; i<DIM; i++)
00730 {
00731 *mpVoronoiFile << node_location[i] << " ";
00732 }
00733
00734 double cell_volume = mpVoronoiTessellation->GetVolumeOfElement(elem_index);
00735 double cell_surface_area = mpVoronoiTessellation->GetSurfaceAreaOfElement(elem_index);
00736 *mpVoronoiFile << cell_volume << " " << cell_surface_area << " ";
00737 }
00738 *mpVoronoiFile << "\n";
00739 }
00740
00741 template<unsigned DIM>
00742 void MeshBasedCellPopulation<DIM>::WriteCellPopulationVolumeResultsToFile()
00743 {
00744 assert(DIM==2 || DIM==3);
00745
00746
00747 *mpCellPopulationVolumesFile << SimulationTime::Instance()->GetTime() << " ";
00748
00749
00750 double total_area = mrMesh.GetVolume();
00751 double apoptotic_area = 0.0;
00752
00753
00754 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
00755 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
00756 ++elem_iter)
00757 {
00758
00759 unsigned elem_index = elem_iter->GetIndex();
00760
00761
00762 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
00763
00764
00765 if (!this->IsGhostNode(node_index))
00766 {
00767
00768 CellPtr p_cell = this->mLocationCellMap[node_index];
00769
00770
00771 bool cell_is_apoptotic = p_cell->HasCellProperty<ApoptoticCellProperty>();
00772 if (cell_is_apoptotic)
00773 {
00774 double cell_volume = mpVoronoiTessellation->GetVolumeOfElement(elem_index);
00775 apoptotic_area += cell_volume;
00776 }
00777 }
00778 }
00779 *mpCellPopulationVolumesFile << total_area << " " << apoptotic_area << "\n";
00780 }
00781
00782 template<unsigned DIM>
00783 void MeshBasedCellPopulation<DIM>::WriteCellVolumeResultsToFile()
00784 {
00785 assert(DIM==2 || DIM==3);
00786
00787
00788 *mpCellVolumesFile << SimulationTime::Instance()->GetTime() << " ";
00789
00790
00791 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
00792 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
00793 ++elem_iter)
00794 {
00795
00796 unsigned elem_index = elem_iter->GetIndex();
00797
00798
00799 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
00800
00801
00802 if (!this->IsGhostNode(node_index))
00803 {
00804
00805 *mpCellVolumesFile << node_index << " ";
00806
00807
00808 CellPtr p_cell = this->mLocationCellMap[node_index];
00809
00810
00811 unsigned cell_index = p_cell->GetCellId();
00812 *mpCellVolumesFile << cell_index << " ";
00813
00814
00815 c_vector<double, DIM> node_location = this->GetNode(node_index)->rGetLocation();
00816 for (unsigned i=0; i<DIM; i++)
00817 {
00818 *mpCellVolumesFile << node_location[i] << " ";
00819 }
00820
00821
00822 double cell_volume = mpVoronoiTessellation->GetVolumeOfElement(elem_index);
00823 *mpCellVolumesFile << cell_volume << " ";
00824 }
00825 }
00826 *mpCellVolumesFile << "\n";
00827 }
00828
00829 template<unsigned DIM>
00830 void MeshBasedCellPopulation<DIM>::SetWriteVtkAsPoints(bool writeVtkAsPoints)
00831 {
00832 mWriteVtkAsPoints = writeVtkAsPoints;
00833 }
00834
00835 template<unsigned DIM>
00836 bool MeshBasedCellPopulation<DIM>::GetWriteVtkAsPoints()
00837 {
00838 return mWriteVtkAsPoints;
00839 }
00840
00842
00844
00845 template<unsigned DIM>
00846 Node<DIM>* MeshBasedCellPopulation<DIM>::SpringIterator::GetNodeA()
00847 {
00848 return mEdgeIter.GetNodeA();
00849 }
00850
00851 template<unsigned DIM>
00852 Node<DIM>* MeshBasedCellPopulation<DIM>::SpringIterator::GetNodeB()
00853 {
00854 return mEdgeIter.GetNodeB();
00855 }
00856
00857 template<unsigned DIM>
00858 CellPtr MeshBasedCellPopulation<DIM>::SpringIterator::GetCellA()
00859 {
00860 assert((*this) != mrCellPopulation.SpringsEnd());
00861 return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeA()->GetIndex());
00862 }
00863
00864 template<unsigned DIM>
00865 CellPtr MeshBasedCellPopulation<DIM>::SpringIterator::GetCellB()
00866 {
00867 assert((*this) != mrCellPopulation.SpringsEnd());
00868 return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeB()->GetIndex());
00869 }
00870
00871 template<unsigned DIM>
00872 bool MeshBasedCellPopulation<DIM>::SpringIterator::operator!=(const MeshBasedCellPopulation<DIM>::SpringIterator& rOther)
00873 {
00874 return (mEdgeIter != rOther.mEdgeIter);
00875 }
00876
00877 template<unsigned DIM>
00878 typename MeshBasedCellPopulation<DIM>::SpringIterator& MeshBasedCellPopulation<DIM>::SpringIterator::operator++()
00879 {
00880 bool edge_is_ghost = false;
00881
00882 do
00883 {
00884 ++mEdgeIter;
00885 if (*this != mrCellPopulation.SpringsEnd())
00886 {
00887 bool a_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
00888 bool b_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
00889
00890 edge_is_ghost = (a_is_ghost || b_is_ghost);
00891 }
00892 }
00893 while (*this!=mrCellPopulation.SpringsEnd() && edge_is_ghost);
00894
00895 return (*this);
00896 }
00897
00898 template<unsigned DIM>
00899 MeshBasedCellPopulation<DIM>::SpringIterator::SpringIterator(
00900 MeshBasedCellPopulation<DIM>& rCellPopulation,
00901 typename MutableMesh<DIM,DIM>::EdgeIterator edgeIter)
00902 : mrCellPopulation(rCellPopulation),
00903 mEdgeIter(edgeIter)
00904 {
00905 if (mEdgeIter!=mrCellPopulation.mrMesh.EdgesEnd())
00906 {
00907 bool a_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
00908 bool b_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
00909
00910 if (a_is_ghost || b_is_ghost)
00911 {
00912 ++(*this);
00913 }
00914 }
00915 }
00916
00917 template<unsigned DIM>
00918 typename MeshBasedCellPopulation<DIM>::SpringIterator MeshBasedCellPopulation<DIM>::SpringsBegin()
00919 {
00920 return SpringIterator(*this, mrMesh.EdgesBegin());
00921 }
00922
00923 template<unsigned DIM>
00924 typename MeshBasedCellPopulation<DIM>::SpringIterator MeshBasedCellPopulation<DIM>::SpringsEnd()
00925 {
00926 return SpringIterator(*this, mrMesh.EdgesEnd());
00927 }
00928
00932 template<>
00933 void MeshBasedCellPopulation<2>::CreateVoronoiTessellation()
00934 {
00935 delete mpVoronoiTessellation;
00936
00937
00938 bool is_mesh_periodic = false;
00939 if (dynamic_cast<Cylindrical2dMesh*>(&mrMesh))
00940 {
00941 is_mesh_periodic = true;
00942 }
00943
00944 mpVoronoiTessellation = new VertexMesh<2, 2>(mrMesh, is_mesh_periodic);
00945 }
00946
00952 template<>
00953 void MeshBasedCellPopulation<3>::CreateVoronoiTessellation()
00954 {
00955 delete mpVoronoiTessellation;
00956 mpVoronoiTessellation = new VertexMesh<3, 3>(mrMesh);
00957 }
00958
00963 template<>
00964 void MeshBasedCellPopulation<1>::CreateVoronoiTessellation()
00965 {
00966
00967 NEVER_REACHED;
00968 }
00969
00970 template<unsigned DIM>
00971 VertexMesh<DIM, DIM>* MeshBasedCellPopulation<DIM>::GetVoronoiTessellation()
00972 {
00973 assert(mpVoronoiTessellation!=NULL);
00974 return mpVoronoiTessellation;
00975 }
00976
00977 template<unsigned DIM>
00978 double MeshBasedCellPopulation<DIM>::GetVolumeOfVoronoiElement(unsigned index)
00979 {
00980 unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
00981 double volume = mpVoronoiTessellation->GetVolumeOfElement(element_index);
00982 return volume;
00983 }
00984
00985 template<unsigned DIM>
00986 double MeshBasedCellPopulation<DIM>::GetSurfaceAreaOfVoronoiElement(unsigned index)
00987 {
00988 unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
00989 double surface_area = mpVoronoiTessellation->GetSurfaceAreaOfElement(element_index);
00990 return surface_area;
00991 }
00992
00993 template<unsigned DIM>
00994 double MeshBasedCellPopulation<DIM>::GetVoronoiEdgeLength(unsigned index1, unsigned index2)
00995 {
00996 unsigned element_index1 = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index1);
00997 unsigned element_index2 = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index2);
00998 double edge_length = mpVoronoiTessellation->GetEdgeLength(element_index1, element_index2);
00999 return edge_length;
01000 }
01001
01002 template<unsigned DIM>
01003 void MeshBasedCellPopulation<DIM>::CheckCellPointers()
01004 {
01005 bool res = true;
01006 for (std::list<CellPtr>::iterator it=this->mCells.begin();
01007 it!=this->mCells.end();
01008 ++it)
01009 {
01010 CellPtr p_cell = *it;
01011 assert(p_cell);
01012 AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
01013 assert(p_model);
01014
01015
01016 unsigned node_index = this->mCellLocationMap[p_cell.get()];
01017 std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
01018 CellPtr p_cell_in_cell_population = this->GetCellUsingLocationIndex(node_index);
01019 #define COVERAGE_IGNORE //Debugging code. Shouldn't fail under normal conditions
01020 if (p_cell_in_cell_population != p_cell)
01021 {
01022 std::cout << " Mismatch with cell population" << std::endl << std::flush;
01023 res = false;
01024 }
01025
01026
01027 if (p_model->GetCell() != p_cell)
01028 {
01029 std::cout << " Mismatch with cycle model" << std::endl << std::flush;
01030 res = false;
01031 }
01032 }
01033 assert(res);
01034 #undef COVERAGE_IGNORE
01035
01036 res = true;
01037 for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = mMarkedSprings.begin();
01038 it1 != mMarkedSprings.end();
01039 ++it1)
01040 {
01041 const std::pair<CellPtr,CellPtr>& r_pair = *it1;
01042
01043 for (unsigned i=0; i<2; i++)
01044 {
01045 CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
01046
01047 assert(p_cell);
01048 AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
01049 assert(p_model);
01050 unsigned node_index = this->mCellLocationMap[p_cell.get()];
01051 std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
01052
01053 #define COVERAGE_IGNORE //Debugging code. Shouldn't fail under normal conditions
01054
01055 if (p_cell->IsDead())
01056 {
01057 std::cout << " Cell is dead" << std::endl << std::flush;
01058 res = false;
01059 }
01060
01061
01062 CellPtr p_cell_in_cell_population = this->GetCellUsingLocationIndex(node_index);
01063 if (p_cell_in_cell_population != p_cell)
01064 {
01065 std::cout << " Mismatch with cell population" << std::endl << std::flush;
01066 res = false;
01067 }
01068
01069
01070 if (p_model->GetCell() != p_cell)
01071 {
01072 std::cout << " Mismatch with cycle model" << std::endl << std::flush;
01073 res = false;
01074 }
01075 }
01076 #undef COVERAGE_IGNORE
01077 }
01078 assert(res);
01079 }
01080
01081 template<unsigned DIM>
01082 std::pair<CellPtr,CellPtr> MeshBasedCellPopulation<DIM>::CreateCellPair(CellPtr pCell1, CellPtr pCell2)
01083 {
01084 assert(pCell1);
01085 assert(pCell2);
01086
01087 std::pair<CellPtr,CellPtr> cell_pair;
01088
01089 if (pCell1->GetCellId() < pCell2->GetCellId())
01090 {
01091 cell_pair.first = pCell1;
01092 cell_pair.second = pCell2;
01093 }
01094 else
01095 {
01096 cell_pair.first = pCell2;
01097 cell_pair.second = pCell1;
01098 }
01099 return cell_pair;
01100 }
01101
01102 template<unsigned DIM>
01103 bool MeshBasedCellPopulation<DIM>::IsMarkedSpring(const std::pair<CellPtr,CellPtr>& rCellPair)
01104 {
01105
01106 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
01107
01108 return mMarkedSprings.find(rCellPair) != mMarkedSprings.end();
01109 }
01110
01111 template<unsigned DIM>
01112 void MeshBasedCellPopulation<DIM>::MarkSpring(std::pair<CellPtr,CellPtr>& rCellPair)
01113 {
01114
01115 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
01116
01117 mMarkedSprings.insert(rCellPair);
01118 }
01119
01120 template<unsigned DIM>
01121 void MeshBasedCellPopulation<DIM>::UnmarkSpring(std::pair<CellPtr,CellPtr>& rCellPair)
01122 {
01123
01124 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
01125
01126 mMarkedSprings.erase(rCellPair);
01127 }
01128
01129 template<unsigned DIM>
01130 double MeshBasedCellPopulation<DIM>::GetAreaBasedDampingConstantParameter()
01131 {
01132 return mAreaBasedDampingConstantParameter;
01133 }
01134
01135 template<unsigned DIM>
01136 void MeshBasedCellPopulation<DIM>::SetAreaBasedDampingConstantParameter(double areaBasedDampingConstantParameter)
01137 {
01138 assert(areaBasedDampingConstantParameter >= 0.0);
01139 mAreaBasedDampingConstantParameter = areaBasedDampingConstantParameter;
01140 }
01141
01142 template<unsigned DIM>
01143 bool MeshBasedCellPopulation<DIM>::GetOutputVoronoiData()
01144 {
01145 return mOutputVoronoiData;
01146 }
01147
01148 template<unsigned DIM>
01149 void MeshBasedCellPopulation<DIM>::SetOutputVoronoiData(bool outputVoronoiData)
01150 {
01151 mOutputVoronoiData = outputVoronoiData;
01152 }
01153
01154 template<unsigned DIM>
01155 bool MeshBasedCellPopulation<DIM>::GetOutputCellPopulationVolumes()
01156 {
01157 return mOutputCellPopulationVolumes;
01158 }
01159
01160 template<unsigned DIM>
01161 void MeshBasedCellPopulation<DIM>::SetOutputCellPopulationVolumes(bool outputCellPopulationVolumes)
01162 {
01163 mOutputCellPopulationVolumes = outputCellPopulationVolumes;
01164 }
01165
01166 template<unsigned DIM>
01167 void MeshBasedCellPopulation<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
01168 {
01169 *rParamsFile << "\t\t<UseAreaBasedDampingConstant>" << mUseAreaBasedDampingConstant << "</UseAreaBasedDampingConstant> \n";
01170 *rParamsFile << "\t\t<AreaBasedDampingConstantParameter>" << mAreaBasedDampingConstantParameter << "</AreaBasedDampingConstantParameter> \n";
01171 *rParamsFile << "\t\t<OutputVoronoiData>" << mOutputVoronoiData << "</OutputVoronoiData> \n";
01172 *rParamsFile << "\t\t<OutputCellPopulationVolumes>" << mOutputCellPopulationVolumes << "</OutputCellPopulationVolumes> \n";
01173
01174
01175 AbstractCentreBasedCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
01176 }
01177
01178 template<unsigned DIM>
01179 double MeshBasedCellPopulation<DIM>::GetWidth(const unsigned& rDimension)
01180 {
01181
01182 double width = mrMesh.GetWidth(rDimension);
01183 return width;
01184 }
01185
01187
01189
01190 template class MeshBasedCellPopulation<1>;
01191 template class MeshBasedCellPopulation<2>;
01192 template class MeshBasedCellPopulation<3>;
01193
01194
01195 #include "SerializationExportWrapperForCpp.hpp"
01196 EXPORT_TEMPLATE_CLASS_SAME_DIMS(MeshBasedCellPopulation)