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 "VertexBasedCellPopulation.hpp"
00030 #include "CellwiseData.hpp"
00031 #include "VertexMeshWriter.hpp"
00032 #include "Warnings.hpp"
00033
00034 template<unsigned DIM>
00035 VertexBasedCellPopulation<DIM>::VertexBasedCellPopulation(MutableVertexMesh<DIM, DIM>& rMesh,
00036 std::vector<CellPtr>& rCells,
00037 bool deleteMesh,
00038 bool validate,
00039 const std::vector<unsigned> locationIndices)
00040 : AbstractOffLatticeCellPopulation<DIM>(rCells, locationIndices),
00041 mrMesh(rMesh),
00042 mDeleteMesh(deleteMesh)
00043 {
00044
00045 bool contains_boundary_nodes = false;
00046 for (typename MutableVertexMesh<DIM,DIM>::NodeIterator node_iter = mrMesh.GetNodeIteratorBegin();
00047 node_iter != mrMesh.GetNodeIteratorEnd();
00048 ++node_iter)
00049 {
00050 if (node_iter->IsBoundaryNode())
00051 {
00052 contains_boundary_nodes = true;
00053 }
00054 }
00055
00057 if (!contains_boundary_nodes)
00058 {
00059 EXCEPTION("No boundary nodes are defined in the supplied vertex mesh which are needed for vertex based simulations.");
00060 }
00061
00062
00063 if (validate)
00064 {
00065 Validate();
00066 }
00067 }
00068
00069 template<unsigned DIM>
00070 VertexBasedCellPopulation<DIM>::VertexBasedCellPopulation(MutableVertexMesh<DIM, DIM>& rMesh)
00071 : AbstractOffLatticeCellPopulation<DIM>(),
00072 mrMesh(rMesh),
00073 mDeleteMesh(true)
00074 {
00075 }
00076
00077 template<unsigned DIM>
00078 VertexBasedCellPopulation<DIM>::~VertexBasedCellPopulation()
00079 {
00080 if (mDeleteMesh)
00081 {
00082 delete &mrMesh;
00083 }
00084 }
00085
00086 template<unsigned DIM>
00087 double VertexBasedCellPopulation<DIM>::GetDampingConstant(unsigned nodeIndex)
00088 {
00089
00090 double average_damping_constant = 0.0;
00091
00092 std::set<unsigned> containing_elements = GetNode(nodeIndex)->rGetContainingElementIndices();
00093 double temp = 1.0/((double) containing_elements.size());
00094
00095 for (std::set<unsigned>::iterator iter = containing_elements.begin();
00096 iter != containing_elements.end();
00097 ++iter)
00098 {
00099 CellPtr p_cell = this->GetCellUsingLocationIndex(*iter);
00100 bool cell_is_wild_type = p_cell->GetMutationState()->IsType<WildTypeCellMutationState>();
00101 bool cell_is_labelled = p_cell->HasCellProperty<CellLabel>();
00102
00103 if (cell_is_wild_type && !cell_is_labelled)
00104 {
00105 average_damping_constant += this->GetDampingConstantNormal()*temp;
00106 }
00107 else
00108 {
00109 average_damping_constant += this->GetDampingConstantMutant()*temp;
00110 }
00111 }
00112
00113 return average_damping_constant;
00114 }
00115
00116 template<unsigned DIM>
00117 MutableVertexMesh<DIM, DIM>& VertexBasedCellPopulation<DIM>::rGetMesh()
00118 {
00119 return mrMesh;
00120 }
00121
00122 template<unsigned DIM>
00123 const MutableVertexMesh<DIM, DIM>& VertexBasedCellPopulation<DIM>::rGetMesh() const
00124 {
00125 return mrMesh;
00126 }
00127
00128 template<unsigned DIM>
00129 VertexElement<DIM, DIM>* VertexBasedCellPopulation<DIM>::GetElement(unsigned elementIndex)
00130 {
00131 return mrMesh.GetElement(elementIndex);
00132 }
00133
00134 template<unsigned DIM>
00135 unsigned VertexBasedCellPopulation<DIM>::GetNumNodes()
00136 {
00137 return mrMesh.GetNumNodes();
00138 }
00139
00140 template<unsigned DIM>
00141 c_vector<double, DIM> VertexBasedCellPopulation<DIM>::GetLocationOfCellCentre(CellPtr pCell)
00142 {
00143 return mrMesh.GetCentroidOfElement(this->mCellLocationMap[pCell.get()]);
00144 }
00145
00146 template<unsigned DIM>
00147 Node<DIM>* VertexBasedCellPopulation<DIM>::GetNode(unsigned index)
00148 {
00149 return mrMesh.GetNode(index);
00150 }
00151
00152 template<unsigned DIM>
00153 unsigned VertexBasedCellPopulation<DIM>::AddNode(Node<DIM>* pNewNode)
00154 {
00155 return mrMesh.AddNode(pNewNode);
00156 }
00157
00158 template<unsigned DIM>
00159 void VertexBasedCellPopulation<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00160 {
00161 mrMesh.SetNode(nodeIndex, rNewLocation);
00162 }
00163
00164 template<unsigned DIM>
00165 VertexElement<DIM, DIM>* VertexBasedCellPopulation<DIM>::GetElementCorrespondingToCell(CellPtr pCell)
00166 {
00167 return mrMesh.GetElement(this->mCellLocationMap[pCell.get()]);
00168 }
00169
00170 template<unsigned DIM>
00171 unsigned VertexBasedCellPopulation<DIM>::GetNumElements()
00172 {
00173 return mrMesh.GetNumElements();
00174 }
00175
00176 template<unsigned DIM>
00177 CellPtr VertexBasedCellPopulation<DIM>::AddCell(CellPtr pNewCell, const c_vector<double,DIM>& rCellDivisionVector, CellPtr pParentCell)
00178 {
00179
00180 VertexElement<DIM, DIM>* p_element = GetElementCorrespondingToCell(pParentCell);
00181
00182
00183 unsigned new_element_index;
00184 if (norm_2(rCellDivisionVector) < DBL_EPSILON)
00185 {
00186
00187 new_element_index = mrMesh.DivideElementAlongShortAxis(p_element, true);
00188 }
00189 else
00190 {
00191
00192 new_element_index = mrMesh.DivideElementAlongGivenAxis(p_element, rCellDivisionVector, true);
00193 }
00194
00195
00196 this->mCells.push_back(pNewCell);
00197
00198
00199 CellPtr p_created_cell = this->mCells.back();
00200 this->mLocationCellMap[new_element_index] = p_created_cell;
00201 this->mCellLocationMap[p_created_cell.get()] = new_element_index;
00202 return p_created_cell;
00203 }
00204
00205 template<unsigned DIM>
00206 unsigned VertexBasedCellPopulation<DIM>::RemoveDeadCells()
00207 {
00208 unsigned num_removed = 0;
00209
00210 for (std::list<CellPtr>::iterator it = this->mCells.begin();
00211 it != this->mCells.end();
00212 ++it)
00213 {
00214 if ((*it)->IsDead())
00215 {
00216
00217 num_removed++;
00218 mrMesh.DeleteElementPriorToReMesh(this->mCellLocationMap[(*it).get()]);
00219 it = this->mCells.erase(it);
00220 --it;
00221 }
00222 }
00223 return num_removed;
00224 }
00225
00226 template<unsigned DIM>
00227 void VertexBasedCellPopulation<DIM>::UpdateNodeLocations(const std::vector< c_vector<double, DIM> >& rNodeForces, double dt)
00228 {
00229
00230 for (unsigned node_index=0; node_index<GetNumNodes(); node_index++)
00231 {
00232
00233 double damping_const = this->GetDampingConstant(node_index);
00234
00235
00236 c_vector<double, DIM> displacement = dt*rNodeForces[node_index]/damping_const;
00237
00238
00239
00240
00241
00242
00243
00244
00245 if (norm_2(displacement) > 0.5*mrMesh.GetCellRearrangementThreshold())
00246 {
00247 WARN_ONCE_ONLY("Vertices are moving more than half the CellRearrangementThreshold. This could cause elements to become inverted so the motion has been restricted. Use a smaller timestep to avoid these warnings.");
00248 displacement *= 0.5*mrMesh.GetCellRearrangementThreshold()/norm_2(displacement);
00249 }
00250
00251
00252 c_vector<double, DIM> new_node_location = this->GetNode(node_index)->rGetLocation() + displacement;
00253
00254 for (unsigned i=0; i<DIM; i++)
00255 {
00256 assert(!std::isnan(new_node_location(i)));
00257 }
00258
00259
00260 ChastePoint<DIM> new_point(new_node_location);
00261
00262
00263 this->SetNode(node_index, new_point);
00264 }
00265 }
00266
00267 template<unsigned DIM>
00268 bool VertexBasedCellPopulation<DIM>::IsCellAssociatedWithADeletedLocation(CellPtr pCell)
00269 {
00270 return GetElementCorrespondingToCell(pCell)->IsDeleted();;
00271 }
00272
00273 template<unsigned DIM>
00274 void VertexBasedCellPopulation<DIM>::Update(bool hasHadBirthsOrDeaths)
00275 {
00276 VertexElementMap element_map(mrMesh.GetNumAllElements());
00277
00278 mrMesh.ReMesh(element_map);
00279
00280 if (!element_map.IsIdentityMap())
00281 {
00282
00283 std::map<Cell*, unsigned> old_map = this->mCellLocationMap;
00284
00285 this->mCellLocationMap.clear();
00286 this->mLocationCellMap.clear();
00287
00288 for (std::list<CellPtr>::iterator cell_iter = this->mCells.begin();
00289 cell_iter != this->mCells.end();
00290 ++cell_iter)
00291 {
00292
00293 unsigned old_elem_index = old_map[(*cell_iter).get()];
00294
00295 if (element_map.IsDeleted(old_elem_index))
00296 {
00301 WARNING("Cell removed due to T2Swap this is not counted in the dead cells counter");
00302 cell_iter = this->mCells.erase(cell_iter);
00303 --cell_iter;
00304 }
00305 else
00306 {
00307 unsigned new_elem_index = element_map.GetNewIndex(old_elem_index);
00308
00309 this->mLocationCellMap[new_elem_index] = *cell_iter;
00310 this->mCellLocationMap[(*cell_iter).get()] = new_elem_index;
00311 }
00312 }
00313
00314
00315 Validate();
00316 }
00317
00318 element_map.ResetToIdentity();
00319 }
00320
00321 template<unsigned DIM>
00322 void VertexBasedCellPopulation<DIM>::Validate()
00323 {
00324
00325 std::vector<unsigned> validated_element = std::vector<unsigned>(this->GetNumElements(), 0);
00326
00327 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00328 cell_iter != this->End();
00329 ++cell_iter)
00330 {
00331 unsigned elem_index = GetLocationIndexUsingCell(*cell_iter);
00332 validated_element[elem_index]++;
00333 }
00334
00335 for (unsigned i=0; i<validated_element.size(); i++)
00336 {
00337 if (validated_element[i] == 0)
00338 {
00339 EXCEPTION("Element " << i << " does not appear to have a cell associated with it");
00340 }
00341
00342 if (validated_element[i] > 1)
00343 {
00344 EXCEPTION("Element " << i << " appears to have " << validated_element[i] << " cells associated with it");
00345 }
00346 }
00347 }
00348
00349 template<unsigned DIM>
00350 void VertexBasedCellPopulation<DIM>::WriteResultsToFiles()
00351 {
00352 AbstractOffLatticeCellPopulation<DIM>::WriteResultsToFiles();
00353
00354 SimulationTime* p_time = SimulationTime::Instance();
00355
00356
00357 *mpT1SwapLocationsFile << p_time->GetTime() << "\t";
00358 std::vector< c_vector<double, DIM> > t1_swap_locations = mrMesh.GetLocationsOfT1Swaps();
00359 *mpT1SwapLocationsFile << t1_swap_locations.size() << "\t";
00360 for (unsigned index = 0; index < t1_swap_locations.size(); index++)
00361 {
00362 for (unsigned i=0; i<DIM; i++)
00363 {
00364 *mpT1SwapLocationsFile << t1_swap_locations[index][i] << "\t";
00365 }
00366 }
00367 *mpT1SwapLocationsFile << "\n";
00368 mrMesh.ClearLocationsOfT1Swaps();
00369
00370
00371 *mpT3SwapLocationsFile << p_time->GetTime() << "\t";
00372 std::vector< c_vector<double, DIM> > t3_swap_locations = mrMesh.GetLocationsOfT3Swaps();
00373 *mpT3SwapLocationsFile << t3_swap_locations.size() << "\t";
00374 for (unsigned index = 0; index < t3_swap_locations.size(); index++)
00375 {
00376 for (unsigned i=0; i<DIM; i++)
00377 {
00378 *mpT3SwapLocationsFile << t3_swap_locations[index][i] << "\t";
00379 }
00380 }
00381 *mpT3SwapLocationsFile << "\n";
00382 mrMesh.ClearLocationsOfT3Swaps();
00383
00384
00385 *mpVizElementsFile << p_time->GetTime() << "\t";
00386
00387
00388 for (std::list<CellPtr>::iterator cell_iter = this->mCells.begin();
00389 cell_iter != this->mCells.end();
00390 ++cell_iter)
00391 {
00392 unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
00393
00394
00395 bool elem_corresponds_to_dead_cell = false;
00396
00397 if (this->mLocationCellMap[elem_index])
00398 {
00399 elem_corresponds_to_dead_cell = this->mLocationCellMap[elem_index]->IsDead();
00400 }
00401
00402
00403 if (!(GetElement(elem_index)->IsDeleted()) && !elem_corresponds_to_dead_cell)
00404 {
00405 VertexElement<DIM, DIM>* p_element = mrMesh.GetElement(elem_index);
00406
00407 unsigned num_nodes_in_element = p_element->GetNumNodes();
00408
00409
00410 *mpVizElementsFile << num_nodes_in_element << " ";
00411
00412
00413 for (unsigned i=0; i<num_nodes_in_element; i++)
00414 {
00415 *mpVizElementsFile << p_element->GetNodeGlobalIndex(i) << " ";
00416 }
00417 }
00418 }
00419 *mpVizElementsFile << "\n";
00420 }
00421
00422 template<unsigned DIM>
00423 void VertexBasedCellPopulation<DIM>::WriteCellVolumeResultsToFile()
00424 {
00425 assert(DIM==2);
00426
00427
00428 *(this->mpCellVolumesFile) << SimulationTime::Instance()->GetTime() << " ";
00429
00430
00431 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00432 cell_iter != this->End();
00433 ++cell_iter)
00434 {
00435 unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
00436
00437
00438 bool elem_corresponds_to_dead_cell = false;
00439
00440 if (this->mLocationCellMap[elem_index])
00441 {
00442 elem_corresponds_to_dead_cell = this->mLocationCellMap[elem_index]->IsDead();
00443 }
00444
00445
00446 if (!(GetElement(elem_index)->IsDeleted()) && !elem_corresponds_to_dead_cell)
00447 {
00448
00449 *(this->mpCellVolumesFile) << elem_index << " ";
00450
00451
00452 unsigned cell_index = (*cell_iter)->GetCellId();
00453 *(this->mpCellVolumesFile) << cell_index << " ";
00454
00455
00456 c_vector<double, DIM> centre_location = GetLocationOfCellCentre(*cell_iter);
00457 for (unsigned i=0; i<DIM; i++)
00458 {
00459 *(this->mpCellVolumesFile) << centre_location[i] << " ";
00460 }
00461
00462
00463 double cell_volume = mrMesh.GetVolumeOfElement(elem_index);
00464 *(this->mpCellVolumesFile) << cell_volume << " ";
00465 }
00466 }
00467 *(this->mpCellVolumesFile) << "\n";
00468 }
00469
00470 template<unsigned DIM>
00471 void VertexBasedCellPopulation<DIM>::WriteVtkResultsToFile()
00472 {
00473 #ifdef CHASTE_VTK
00474 SimulationTime* p_time = SimulationTime::Instance();
00475
00476 VertexMeshWriter<DIM, DIM> mesh_writer(this->mDirPath, "results", false);
00477 std::stringstream time;
00478 time << p_time->GetTimeStepsElapsed();
00479
00480 unsigned num_elements = mrMesh.GetNumElements();
00481 std::vector<double> cell_types(num_elements);
00482 std::vector<double> cell_ancestors(num_elements);
00483 std::vector<double> cell_mutation_states(num_elements);
00484 std::vector<double> cell_ages(num_elements);
00485 std::vector<double> cell_cycle_phases(num_elements);
00486 std::vector<double> cell_volumes(num_elements);
00487 std::vector<std::vector<double> > cellwise_data;
00488
00489 if (CellwiseData<DIM>::Instance()->IsSetUp())
00490 {
00491 CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00492 unsigned num_variables = p_data->GetNumVariables();
00493 for (unsigned var=0; var<num_variables; var++)
00494 {
00495 std::vector<double> cellwise_data_var(num_elements);
00496 cellwise_data.push_back(cellwise_data_var);
00497 }
00498 }
00499
00500
00501 for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mrMesh.GetElementIteratorBegin();
00502 elem_iter != mrMesh.GetElementIteratorEnd();
00503 ++elem_iter)
00504 {
00505
00506 unsigned elem_index = elem_iter->GetIndex();
00507
00508
00509 CellPtr p_cell = this->mLocationCellMap[elem_index];
00510 assert(p_cell);
00511
00512 if (this->mOutputCellAncestors)
00513 {
00514 double ancestor_index = (p_cell->GetAncestor() == UNSIGNED_UNSET) ? (-1.0) : (double)p_cell->GetAncestor();
00515 cell_ancestors[elem_index] = ancestor_index;
00516 }
00517 if (this->mOutputCellProliferativeTypes)
00518 {
00519 double cell_type = p_cell->GetCellCycleModel()->GetCellProliferativeType();
00520 cell_types[elem_index] = cell_type;
00521 }
00522 if (this->mOutputCellMutationStates)
00523 {
00524 double mutation_state = p_cell->GetMutationState()->GetColour();
00525 cell_mutation_states[elem_index] = mutation_state;
00526 }
00527 if (this->mOutputCellAges)
00528 {
00529 double age = p_cell->GetAge();
00530 cell_ages[elem_index] = age;
00531 }
00532 if (this->mOutputCellCyclePhases)
00533 {
00534 double cycle_phase = p_cell->GetCellCycleModel()->GetCurrentCellCyclePhase();
00535 cell_cycle_phases[elem_index] = cycle_phase;
00536 }
00537 if (this->mOutputCellVolumes)
00538 {
00539 double cell_volume = mrMesh.GetVolumeOfElement(elem_index);
00540 cell_volumes[elem_index] = cell_volume;
00541 }
00542 if (CellwiseData<DIM>::Instance()->IsSetUp())
00543 {
00544 CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00545 unsigned num_variables = p_data->GetNumVariables();
00546
00547 for (unsigned var=0; var<num_variables; var++)
00548 {
00549 cellwise_data[var][elem_index] = p_data->GetValue(p_cell, var);
00550 }
00551 }
00552 }
00553
00554 if (this->mOutputCellProliferativeTypes)
00555 {
00556 mesh_writer.AddCellData("Cell types", cell_types);
00557 }
00558 if (this->mOutputCellAncestors)
00559 {
00560 mesh_writer.AddCellData("Ancestors", cell_ancestors);
00561 }
00562 if (this->mOutputCellMutationStates)
00563 {
00564 mesh_writer.AddCellData("Mutation states", cell_mutation_states);
00565 }
00566 if (this->mOutputCellAges)
00567 {
00568 mesh_writer.AddCellData("Ages", cell_ages);
00569 }
00570 if (this->mOutputCellCyclePhases)
00571 {
00572 mesh_writer.AddCellData("Cycle phases", cell_cycle_phases);
00573 }
00574 if (this->mOutputCellVolumes)
00575 {
00576 mesh_writer.AddCellData("Cell volumes", cell_volumes);
00577 }
00578 if (CellwiseData<DIM>::Instance()->IsSetUp())
00579 {
00580 for (unsigned var=0; var<cellwise_data.size(); var++)
00581 {
00582 std::stringstream data_name;
00583 data_name << "Cellwise data " << var;
00584 std::vector<double> cellwise_data_var = cellwise_data[var];
00585 mesh_writer.AddCellData(data_name.str(), cellwise_data_var);
00586 }
00587 }
00588
00589 mesh_writer.WriteVtkUsingMesh(mrMesh, time.str());
00590 *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
00591 *(this->mpVtkMetaFile) << p_time->GetTimeStepsElapsed();
00592 *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
00593 *(this->mpVtkMetaFile) << p_time->GetTimeStepsElapsed();
00594 *(this->mpVtkMetaFile) << ".vtu\"/>\n";
00595 #endif //CHASTE_VTK
00596 }
00597
00598 template<unsigned DIM>
00599 void VertexBasedCellPopulation<DIM>::CreateOutputFiles(const std::string& rDirectory, bool cleanOutputDirectory)
00600 {
00601 AbstractOffLatticeCellPopulation<DIM>::CreateOutputFiles(rDirectory, cleanOutputDirectory);
00602
00603 OutputFileHandler output_file_handler(rDirectory, cleanOutputDirectory);
00604 mpVizElementsFile = output_file_handler.OpenOutputFile("results.vizelements");
00605 mpT1SwapLocationsFile = output_file_handler.OpenOutputFile("T1SwapLocations.dat");
00606 mpT3SwapLocationsFile = output_file_handler.OpenOutputFile("T3SwapLocations.dat");
00607 }
00608
00609 template<unsigned DIM>
00610 void VertexBasedCellPopulation<DIM>::CloseOutputFiles()
00611 {
00612 AbstractOffLatticeCellPopulation<DIM>::CloseOutputFiles();
00613 mpVizElementsFile->close();
00614 mpT1SwapLocationsFile->close();
00615 mpT3SwapLocationsFile->close();
00616 }
00617
00618 template<unsigned DIM>
00619 void VertexBasedCellPopulation<DIM>::GenerateCellResultsAndWriteToFiles()
00620 {
00621
00622 unsigned num_cell_types = this->mCellProliferativeTypeCount.size();
00623 std::vector<unsigned> cell_type_counter(num_cell_types);
00624 for (unsigned i=0; i<num_cell_types; i++)
00625 {
00626 cell_type_counter[i] = 0;
00627 }
00628
00629
00630 unsigned num_cell_cycle_phases = this->mCellCyclePhaseCount.size();
00631 std::vector<unsigned> cell_cycle_phase_counter(num_cell_cycle_phases);
00632 for (unsigned i=0; i<num_cell_cycle_phases; i++)
00633 {
00634 cell_cycle_phase_counter[i] = 0;
00635 }
00636
00637 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00638 cell_iter != this->End();
00639 ++cell_iter)
00640 {
00641 this->GenerateCellResults(this->GetLocationIndexUsingCell(*cell_iter), cell_type_counter, cell_cycle_phase_counter);
00642 }
00643
00644 this->WriteCellResultsToFiles(cell_type_counter, cell_cycle_phase_counter);
00645 }
00646
00647 template<unsigned DIM>
00648 void VertexBasedCellPopulation<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00649 {
00650 *rParamsFile << "\t\t<CellRearrangementThreshold>" << mrMesh.GetCellRearrangementThreshold() << "</CellRearrangementThreshold>\n";
00651 *rParamsFile << "\t\t<T2Threshold>" << mrMesh.GetT2Threshold() << "</T2Threshold>\n";
00652 *rParamsFile << "\t\t<CellRearrangementRatio>" << mrMesh.GetCellRearrangementRatio() << "</CellRearrangementRatio>\n";
00653
00654
00655 AbstractOffLatticeCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
00656 }
00657
00658 template<unsigned DIM>
00659 double VertexBasedCellPopulation<DIM>::GetWidth(const unsigned& rDimension)
00660 {
00661
00662 double width = mrMesh.GetWidth(rDimension);
00663
00664 return width;
00665 }
00666
00667 template<unsigned DIM>
00668 std::set<unsigned> VertexBasedCellPopulation<DIM>::GetNeighbouringNodeIndices(unsigned index)
00669 {
00670 return mrMesh.GetNeighbouringNodeIndices(index);
00671 }
00672
00674
00676
00677 template class VertexBasedCellPopulation<1>;
00678 template class VertexBasedCellPopulation<2>;
00679 template class VertexBasedCellPopulation<3>;
00680
00681
00682 #include "SerializationExportWrapperForCpp.hpp"
00683 EXPORT_TEMPLATE_CLASS_SAME_DIMS(VertexBasedCellPopulation)