NodeBasedCellPopulationWithParticles.cpp
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
00030
00031
00032
00033
00034
00035
00036 #include "NodeBasedCellPopulationWithParticles.hpp"
00037 #include "VtkMeshWriter.hpp"
00038 #include "CellAgesWriter.hpp"
00039 #include "CellAncestorWriter.hpp"
00040 #include "CellProliferativePhasesWriter.hpp"
00041 #include "CellProliferativeTypesWriter.hpp"
00042 #include "CellVolumesWriter.hpp"
00043 #include "CellMutationStatesCountWriter.hpp"
00044
00045 template<unsigned DIM>
00046 NodeBasedCellPopulationWithParticles<DIM>::NodeBasedCellPopulationWithParticles(NodesOnlyMesh<DIM>& rMesh,
00047 std::vector<CellPtr>& rCells,
00048 const std::vector<unsigned> locationIndices,
00049 bool deleteMesh)
00050 : NodeBasedCellPopulation<DIM>(rMesh, rCells, locationIndices, deleteMesh, false)
00051 {
00052 EXCEPT_IF_NOT(PetscTools::IsSequential());
00053 if (!locationIndices.empty())
00054 {
00055
00056 std::set<unsigned> node_indices;
00057 std::set<unsigned> location_indices;
00058 std::set<unsigned> particle_indices;
00059
00060 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = rMesh.GetNodeIteratorBegin();
00061 node_iter != rMesh.GetNodeIteratorEnd();
00062 ++node_iter)
00063 {
00064 node_indices.insert(node_iter->GetIndex());
00065 }
00066 for (unsigned i=0; i<locationIndices.size(); i++)
00067 {
00068 location_indices.insert(locationIndices[i]);
00069 }
00070
00071 std::set_difference(node_indices.begin(), node_indices.end(),
00072 location_indices.begin(), location_indices.end(),
00073 std::inserter(particle_indices, particle_indices.begin()));
00074
00075
00076 SetParticles(particle_indices);
00077 }
00078 else
00079 {
00080 for (typename NodesOnlyMesh<DIM>::NodeIterator node_iter = rMesh.GetNodeIteratorBegin();
00081 node_iter != rMesh.GetNodeIteratorEnd();
00082 ++node_iter)
00083 {
00084 (*node_iter).SetIsParticle(false);
00085 }
00086 NodeBasedCellPopulationWithParticles::Validate();
00087 }
00088 }
00089
00090 template<unsigned DIM>
00091 NodeBasedCellPopulationWithParticles<DIM>::NodeBasedCellPopulationWithParticles(NodesOnlyMesh<DIM>& rMesh)
00092 : NodeBasedCellPopulation<DIM>(rMesh)
00093 {
00094 }
00095
00096 template<unsigned DIM>
00097 bool NodeBasedCellPopulationWithParticles<DIM>::IsParticle(unsigned index)
00098 {
00099 return this->GetNode(index)->IsParticle();
00100 }
00101
00102 template<unsigned DIM>
00103 std::set<unsigned> NodeBasedCellPopulationWithParticles<DIM>::GetParticleIndices()
00104 {
00105 std::set<unsigned> particle_indices;
00106
00107 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00108 node_iter != this->mrMesh.GetNodeIteratorEnd();
00109 ++node_iter)
00110 {
00111 if (node_iter->IsParticle())
00112 {
00113 particle_indices.insert(node_iter->GetIndex());
00114 }
00115 }
00116
00117 return particle_indices;
00118 }
00119
00120 template<unsigned DIM>
00121 void NodeBasedCellPopulationWithParticles<DIM>::SetParticles(const std::set<unsigned>& rParticleIndices)
00122 {
00123 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00124 node_iter != this->mrMesh.GetNodeIteratorEnd();
00125 ++node_iter)
00126 {
00127 if (rParticleIndices.find(node_iter->GetIndex()) != rParticleIndices.end())
00128 {
00129 node_iter->SetIsParticle(true);
00130 }
00131 }
00132 NodeBasedCellPopulationWithParticles::Validate();
00133 }
00134
00135 template<unsigned DIM>
00136 void NodeBasedCellPopulationWithParticles<DIM>::UpdateParticlePositions(double dt)
00137 {
00138
00139 std::vector<c_vector<double, DIM> > drdt(this->GetNumNodes());
00140 for (unsigned i=0; i<drdt.size(); i++)
00141 {
00142 drdt[i] = zero_vector<double>(DIM);
00143 }
00144
00145
00146 double damping_constant = this->GetDampingConstantNormal();
00147 for (unsigned i=0; i<drdt.size(); i++)
00148 {
00149 drdt[i] = this->GetNode(i)->rGetAppliedForce()/damping_constant;
00150 }
00151
00152 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00153 node_iter != this->mrMesh.GetNodeIteratorEnd();
00154 ++node_iter)
00155 {
00156 if (node_iter->IsParticle())
00157 {
00158 ChastePoint<DIM> new_point(node_iter->rGetLocation() + dt*drdt[node_iter->GetIndex()]);
00159 node_iter->SetPoint(new_point);
00160 }
00161 }
00162 }
00163
00164 template<unsigned DIM>
00165 void NodeBasedCellPopulationWithParticles<DIM>::UpdateParticlesAfterReMesh(NodeMap& rMap)
00166 {
00167 }
00168
00169 template<unsigned DIM>
00170 CellPtr NodeBasedCellPopulationWithParticles<DIM>::AddCell(CellPtr pNewCell, const c_vector<double,DIM>& rCellDivisionVector, CellPtr pParentCell)
00171 {
00172 assert(pNewCell);
00173
00174
00175 CellPtr p_created_cell = AbstractCentreBasedCellPopulation<DIM>::AddCell(pNewCell, rCellDivisionVector, pParentCell);
00176 assert(p_created_cell == pNewCell);
00177
00178
00179 unsigned node_index = this->GetLocationIndexUsingCell(p_created_cell);
00180 this->GetNode(node_index)->SetRadius(0.5);
00181 this->GetNode(node_index)->SetIsParticle(false);
00182
00183
00184 return p_created_cell;
00185 }
00186
00187 template<unsigned DIM>
00188 void NodeBasedCellPopulationWithParticles<DIM>::Validate()
00189 {
00190 std::map<unsigned, bool> validated_nodes;
00191 for (typename AbstractMesh<DIM, DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00192 node_iter != this->mrMesh.GetNodeIteratorEnd();
00193 ++node_iter)
00194 {
00195 validated_nodes[node_iter->GetIndex()] = node_iter->IsParticle();
00196 }
00197
00198
00199 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00200 {
00201 unsigned node_index = this->GetLocationIndexUsingCell((*cell_iter));
00202
00203
00204 if (this->GetNode(node_index)->IsParticle())
00205 {
00206 EXCEPTION("Node " << node_index << " is labelled as a particle and has a cell attached");
00207 }
00208 validated_nodes[node_index] = true;
00209 }
00210
00211 for (std::map<unsigned, bool>::iterator map_iter = validated_nodes.begin();
00212 map_iter != validated_nodes.end();
00213 map_iter++)
00214 {
00215 if (!map_iter->second)
00216 {
00217 EXCEPTION("Node " << map_iter->first << " does not appear to be a particle or has a cell associated with it");
00218 }
00219 }
00220 }
00221
00222 template<unsigned DIM>
00223 void NodeBasedCellPopulationWithParticles<DIM>::UpdateNodeLocations(double dt)
00224 {
00225
00226 UpdateParticlePositions(dt);
00227
00228
00229 AbstractCentreBasedCellPopulation<DIM>::UpdateNodeLocations(dt);
00230 }
00231
00232 template<unsigned DIM>
00233 void NodeBasedCellPopulationWithParticles<DIM>::WriteVtkResultsToFile(const std::string& rDirectory)
00234 {
00235 #ifdef CHASTE_VTK
00236
00237 std::stringstream time;
00238 time << SimulationTime::Instance()->GetTimeStepsElapsed();
00239
00240
00241 NodeMap map(1 + this->mpNodesOnlyMesh->GetMaximumNodeIndex());
00242 this->mpNodesOnlyMesh->ReMesh(map);
00243
00244
00245 unsigned num_nodes = this->GetNumNodes();
00246 std::vector<double> rank(num_nodes);
00247 std::vector<double> particles(num_nodes);
00248
00249 unsigned num_cell_data_items = 0;
00250 std::vector<std::string> cell_data_names;
00251
00252
00253 if (num_nodes > 0)
00254 {
00255 num_cell_data_items = this->Begin()->GetCellData()->GetNumItems();
00256 cell_data_names = this->Begin()->GetCellData()->GetKeys();
00257 }
00258
00259 std::vector<std::vector<double> > cell_data;
00260 for (unsigned var=0; var<num_cell_data_items; var++)
00261 {
00262 std::vector<double> cell_data_var(num_nodes);
00263 cell_data.push_back(cell_data_var);
00264 }
00265
00266
00267 VtkMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results_"+time.str(), false);
00268 mesh_writer.SetParallelFiles(*(this->mpNodesOnlyMesh));
00269
00270
00271 for (typename std::vector<boost::shared_ptr<AbstractCellWriter<DIM, DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin();
00272 cell_writer_iter != this->mCellWriters.end();
00273 ++cell_writer_iter)
00274 {
00275
00276 std::vector<double> vtk_cell_data(num_nodes);
00277
00278
00279 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00280 node_iter != this->mrMesh.GetNodeIteratorEnd();
00281 ++node_iter)
00282 {
00283 unsigned node_index = node_iter->GetIndex();
00284
00285
00286 if (this->IsParticle(node_index))
00287 {
00288 vtk_cell_data[node_index] = -2.0;
00289 }
00290 else
00291 {
00292
00293 CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
00294 vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this);
00295 }
00296 }
00297
00298 mesh_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
00299 }
00300
00301
00302 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00303 cell_iter != this->End();
00304 ++cell_iter)
00305 {
00306
00307 unsigned global_index = this->GetLocationIndexUsingCell(*cell_iter);
00308 unsigned node_index = this->rGetMesh().SolveNodeMapping(global_index);
00309
00310 for (unsigned var=0; var<num_cell_data_items; var++)
00311 {
00312 cell_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]);
00313 }
00314
00315 rank[node_index] = (PetscTools::GetMyRank());
00316 }
00317
00318 mesh_writer.AddPointData("Process rank", rank);
00319
00320
00321 for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
00322 node_iter != this->mrMesh.GetNodeIteratorEnd();
00323 ++node_iter)
00324 {
00325 unsigned node_index = node_iter->GetIndex();
00326 particles[node_index] = (double) (this->IsParticle(node_index));
00327 }
00328
00329 mesh_writer.AddPointData("Non-particles", particles);
00330
00331 if (num_cell_data_items > 0)
00332 {
00333 for (unsigned var=0; var<cell_data.size(); var++)
00334 {
00335 mesh_writer.AddPointData(cell_data_names[var], cell_data[var]);
00336 }
00337 }
00338
00339 mesh_writer.WriteFilesUsingMesh(*(this->mpNodesOnlyMesh));
00340
00341 *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
00342 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00343 *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
00344 *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed();
00345 EXCEPT_IF_NOT(PetscTools::IsSequential());
00346 {
00347 *(this->mpVtkMetaFile) << ".vtu\"/>\n";
00348 }
00349
00350
00351
00352
00353 #endif //CHASTE_VTK
00354 }
00355
00356 template<unsigned DIM>
00357 void NodeBasedCellPopulationWithParticles<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00358 {
00359
00360 NodeBasedCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
00361 }
00362
00363
00364 template class NodeBasedCellPopulationWithParticles<1>;
00365 template class NodeBasedCellPopulationWithParticles<2>;
00366 template class NodeBasedCellPopulationWithParticles<3>;
00367
00368
00369 #include "SerializationExportWrapperForCpp.hpp"
00370 EXPORT_TEMPLATE_CLASS_SAME_DIMS(NodeBasedCellPopulationWithParticles)