36 #include "MeshBasedCellPopulationWithGhostNodes.hpp"
39 #include "CellAgesWriter.hpp"
40 #include "CellAncestorWriter.hpp"
41 #include "CellProliferativePhasesWriter.hpp"
42 #include "CellProliferativeTypesWriter.hpp"
43 #include "CellVolumesWriter.hpp"
44 #include "CellLocationIndexWriter.hpp"
47 #include "CellMutationStatesCountWriter.hpp"
49 template<
unsigned DIM>
52 std::vector<CellPtr>& rCells,
53 const std::vector<unsigned> locationIndices,
55 double ghostSpringStiffness)
57 mGhostSpringStiffness(ghostSpringStiffness)
59 if (!locationIndices.empty())
62 std::set<unsigned> node_indices;
63 std::set<unsigned> location_indices;
64 std::set<unsigned> ghost_node_indices;
68 node_indices.insert(this->
GetNode(i)->GetIndex());
70 for (
unsigned i=0; i<locationIndices.size(); i++)
72 location_indices.insert(locationIndices[i]);
75 std::set_difference(node_indices.begin(), node_indices.end(),
76 location_indices.begin(), location_indices.end(),
77 std::inserter(ghost_node_indices, ghost_node_indices.begin()));
89 template<
unsigned DIM>
91 double ghostSpringStiffness)
93 mGhostSpringStiffness(ghostSpringStiffness)
97 template<
unsigned DIM>
102 template<
unsigned DIM>
105 return this->mIsGhostNode;
108 template<
unsigned DIM>
111 return this->mIsGhostNode[index];
114 template<
unsigned DIM>
117 std::set<unsigned> ghost_node_indices;
118 for (
unsigned i=0; i<this->mIsGhostNode.size(); i++)
120 if (this->mIsGhostNode[i])
122 ghost_node_indices.insert(i);
125 return ghost_node_indices;
128 template<
unsigned DIM>
132 this->mIsGhostNode = std::vector<bool>(this->mrMesh.GetNumNodes(),
false);
135 for (std::set<unsigned>::iterator iter=rGhostNodeIndices.begin(); iter!=rGhostNodeIndices.end(); ++iter)
137 this->mIsGhostNode[*iter] =
true;
143 template<
unsigned DIM>
147 std::vector<c_vector<double, DIM> > drdt(this->GetNumNodes());
148 for (
unsigned i=0; i<drdt.size(); i++)
150 drdt[i] = zero_vector<double>(DIM);
158 unsigned nodeA_global_index = edge_iterator.GetNodeA()->GetIndex();
159 unsigned nodeB_global_index = edge_iterator.GetNodeB()->GetIndex();
161 c_vector<double, DIM> force = CalculateForceBetweenGhostNodes(nodeA_global_index, nodeB_global_index);
163 double damping_constant = this->GetDampingConstantNormal();
165 if (!this->mIsGhostNode[nodeA_global_index])
167 drdt[nodeB_global_index] -= force / damping_constant;
171 drdt[nodeA_global_index] += force / damping_constant;
173 if (this->mIsGhostNode[nodeB_global_index])
175 drdt[nodeB_global_index] -= force / damping_constant;
181 node_iter != this->mrMesh.GetNodeIteratorEnd();
184 unsigned node_index = node_iter->GetIndex();
185 if (this->mIsGhostNode[node_index])
187 ChastePoint<DIM> new_point(node_iter->rGetLocation() + dt*drdt[node_index]);
193 template<
unsigned DIM>
196 assert(rNodeAGlobalIndex != rNodeBGlobalIndex);
197 c_vector<double, DIM> unit_difference;
198 c_vector<double, DIM> node_a_location = this->GetNode(rNodeAGlobalIndex)->rGetLocation();
199 c_vector<double, DIM> node_b_location = this->GetNode(rNodeBGlobalIndex)->rGetLocation();
202 unit_difference = this->mrMesh.GetVectorFromAtoB(node_a_location, node_b_location);
204 double distance_between_nodes = norm_2(unit_difference);
205 unit_difference /= distance_between_nodes;
207 double rest_length = 1.0;
209 return mGhostSpringStiffness * unit_difference * (distance_between_nodes - rest_length);
212 template<
unsigned DIM>
217 assert(p_created_cell == pNewCell);
220 unsigned new_node_index = this->GetLocationIndexUsingCell(p_created_cell);
222 if (this->GetNumNodes() > this->mIsGhostNode.size())
224 this->mIsGhostNode.resize(this->GetNumNodes());
225 this->mIsGhostNode[new_node_index] =
false;
229 return p_created_cell;
232 template<
unsigned DIM>
236 std::vector<bool> validated_node = mIsGhostNode;
237 assert(mIsGhostNode.size()==this->GetNumNodes());
242 unsigned node_index = this->GetLocationIndexUsingCell((*cell_iter));
245 if (mIsGhostNode[node_index])
247 EXCEPTION(
"Node " << node_index <<
" is labelled as a ghost node and has a cell attached");
249 validated_node[node_index] =
true;
252 for (
unsigned i=0; i<validated_node.size(); i++)
254 if (!validated_node[i])
256 EXCEPTION(
"Node " << i <<
" does not appear to be a ghost node or have a cell associated with it");
261 template<
unsigned DIM>
265 std::vector<bool> ghost_nodes_before_remesh = mIsGhostNode;
268 mIsGhostNode.clear();
269 mIsGhostNode.resize(this->GetNumNodes());
272 for (
unsigned old_index=0; old_index<rMap.
GetSize(); old_index++)
277 mIsGhostNode[new_index] = ghost_nodes_before_remesh[old_index];
282 template<
unsigned DIM>
285 unsigned node_index = this->GetLocationIndexUsingCell(pCell);
286 std::set<unsigned> neighbour_indices = this->GetNeighbouringNodeIndices(node_index);
289 for (std::set<unsigned>::iterator iter = neighbour_indices.begin();
290 iter != neighbour_indices.end();)
292 if (this->IsGhostNode(*iter))
294 neighbour_indices.erase(iter++);
302 return neighbour_indices;
305 template<
unsigned DIM>
313 if (! this->IsGhostNode(node_iter->GetIndex()))
316 cell_writer_iter != this->mCellWriters.end();
319 CellPtr cell_from_node = this->GetCellUsingLocationIndex(node_iter->GetIndex());
320 this->AcceptCellWriter(*cell_writer_iter, cell_from_node);
326 template<
unsigned DIM>
330 UpdateGhostPositions(dt);
337 template<
unsigned DIM>
340 if (this->mOutputResultsForChasteVisualizer)
342 if (!this->
template HasWriter<CellLocationIndexWriter>())
344 this->
template AddCellWriter<CellLocationIndexWriter>();
351 template<
unsigned DIM>
355 if (this->mpVoronoiTessellation != NULL)
358 std::stringstream time;
359 time << num_timesteps;
365 unsigned num_vtk_cells = this->mpVoronoiTessellation->GetNumElements();
367 cell_writer_iter != this->mCellWriters.end();
371 std::vector<double> vtk_cell_data(num_vtk_cells);
375 elem_iter != this->mpVoronoiTessellation->GetElementIteratorEnd();
379 unsigned elem_index = elem_iter->GetIndex();
380 unsigned node_index = this->mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
383 if (this->IsGhostNode(node_index))
386 vtk_cell_data[elem_index] = -1.0;
391 CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
394 vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell,
this);
398 mesh_writer.
AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
403 std::vector<double> ghosts(num_vtk_cells);
405 elem_iter != this->mpVoronoiTessellation->GetElementIteratorEnd();
408 unsigned elem_index = elem_iter->GetIndex();
409 unsigned node_index = this->mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
410 ghosts[elem_index] = (
double) (this->IsGhostNode(node_index));
417 *(this->mpVtkMetaFile) <<
" <DataSet timestep=\"";
418 *(this->mpVtkMetaFile) << num_timesteps;
419 *(this->mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"results_";
420 *(this->mpVtkMetaFile) << num_timesteps;
421 *(this->mpVtkMetaFile) <<
".vtu\"/>\n";
426 template<
unsigned DIM>
429 *rParamsFile <<
"\t\t<GhostSpringStiffness>" << mGhostSpringStiffness <<
"</GhostSpringStiffness>\n";
void UpdateGhostNodesAfterReMesh(NodeMap &rMap)
void AddCellData(std::string dataName, std::vector< double > dataPayload)
std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
void UpdateNodeLocations(double dt)
virtual CellPtr AddCell(CellPtr pNewCell, const c_vector< double, SPACE_DIM > &rCellDivisionVector, CellPtr pParentCell)
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
std::set< unsigned > GetGhostNodeIndices()
void UpdateGhostPositions(double dt)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
#define EXCEPTION(message)
static SimulationTime * Instance()
bool IsGhostNode(unsigned index)
NodeIterator GetNodeIteratorEnd()
unsigned GetTimeStepsElapsed() const
virtual void AcceptCellWritersAcrossPopulation()
CellPtr AddCell(CellPtr pNewCell, const c_vector< double, DIM > &rCellDivisionVector, CellPtr pParentCell)
virtual void SetNode(unsigned index, ChastePoint< SPACE_DIM > point, bool concreteMove=true)
c_vector< double, DIM > CalculateForceBetweenGhostNodes(const unsigned &rNodeAGlobalIndex, const unsigned &rNodeBGlobalIndex)
MeshBasedCellPopulationWithGhostNodes(MutableMesh< DIM, DIM > &rMesh, std::vector< CellPtr > &rCells, const std::vector< unsigned > locationIndices=std::vector< unsigned >(), bool deleteMesh=false, double ghostSpringStiffness=15.0)
VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
void SetGhostNodes(const std::set< unsigned > &rGhostNodeIndices)
void WriteVtkUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::string stamp="")
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
Node< ELEMENT_DIM > * GetNode(unsigned index)
bool IsDeleted(unsigned index)
unsigned GetNewIndex(unsigned oldIndex) const
std::vector< bool > & rGetGhostNodes()
virtual void UpdateNodeLocations(double dt)
void OutputCellPopulationParameters(out_stream &rParamsFile)
std::vector< bool > mIsGhostNode
void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual ~MeshBasedCellPopulationWithGhostNodes()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)