Chaste  Release::3.4
CellPopulationAdjacencyMatrixWriter.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "CellPopulationAdjacencyMatrixWriter.hpp"
37 #include "AbstractCellPopulation.hpp"
38 #include "MeshBasedCellPopulation.hpp"
39 #include "CaBasedCellPopulation.hpp"
40 #include "NodeBasedCellPopulation.hpp"
41 #include "PottsBasedCellPopulation.hpp"
42 #include "VertexBasedCellPopulation.hpp"
43 
44 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
46  : AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM>("cellpopulationadjacency.dat")
47 {
48 }
49 
50 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
52 {
53  // Make sure the cell population is updated
55  pCellPopulation->Update();
56 
57  unsigned num_cells = pCellPopulation->GetNumRealCells();
58 
59  // Store a map between cells numbered 1 to n and location indices
60  std::map<unsigned,unsigned> local_cell_id_location_index_map;
61 
62  unsigned local_cell_id = 0;
63  for (typename AbstractCellPopulation<SPACE_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
64  cell_iter != pCellPopulation->End();
65  ++cell_iter)
66  {
67  local_cell_id_location_index_map[pCellPopulation->GetLocationIndexUsingCell(*cell_iter)] = local_cell_id;
68  local_cell_id++;
69  }
70  assert(local_cell_id = num_cells+1);
71 
72  // Iterate over cells and calculate the adjacency matrix (stored as a long vector)
73  std::vector<double> adjacency_matrix(num_cells*num_cells);
74  for (unsigned i=0; i<num_cells*num_cells; i++)
75  {
76  adjacency_matrix[i] = 0;
77  }
78 
79  for (typename AbstractCellPopulation<SPACE_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
80  cell_iter != pCellPopulation->End();
81  ++cell_iter)
82  {
83  // Determine whether this cell is labelled
84  bool cell_is_labelled = cell_iter->template HasCellProperty<CellLabel>();
85 
86  // Get the location index corresponding to this cell
87  unsigned index = pCellPopulation->GetLocationIndexUsingCell(*cell_iter);
88 
89  // Get the set of neighbouring location indices
90  std::set<unsigned> neighbour_indices = pCellPopulation->GetNeighbouringLocationIndices(*cell_iter);
91 
92  // If this cell has any neighbours (as defined by mesh/population/interaction distance)...
93  if (!neighbour_indices.empty())
94  {
95  unsigned local_cell_index = local_cell_id_location_index_map[index];
96 
97  for (std::set<unsigned>::iterator neighbour_iter = neighbour_indices.begin();
98  neighbour_iter != neighbour_indices.end();
99  ++neighbour_iter)
100  {
101  // If both cell_iter and p_neighbour_cell are not labelled, then set type_of_link to 1
102  unsigned type_of_link = 1;
103 
104  // Determine whether this neighbour is labelled
105  CellPtr p_neighbour_cell = pCellPopulation->GetCellUsingLocationIndex(*neighbour_iter);
106  bool neighbour_is_labelled = p_neighbour_cell->template HasCellProperty<CellLabel>();
107 
108  if (cell_is_labelled != neighbour_is_labelled)
109  {
110  // Here cell_iter is labelled but p_neighbour_cell is not, or vice versa, so set type_of_link to 3
111  type_of_link = 3;
112  }
113  else if (cell_is_labelled)
114  {
115  // Here both cell_iter and p_neighbour_cell are labelled, so set type_of_link to 2
116  type_of_link = 2;
117  }
118 
119  unsigned local_neighbour_index = local_cell_id_location_index_map[*neighbour_iter];
120  adjacency_matrix[local_cell_index + num_cells*local_neighbour_index] = type_of_link;
121  adjacency_matrix[num_cells*local_cell_index + local_neighbour_index] = type_of_link;
122  }
123  }
124  }
125 
126  // Output the number of cells and the elements of the adjacency matrix
127  *this->mpOutStream << num_cells << "\t";
128  for (unsigned i=0; i<num_cells*num_cells; i++)
129  {
130  *this->mpOutStream << adjacency_matrix[i] << "\t";
131  }
132 }
133 
134 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
136 {
137  // Make sure the cell population is updated
139  pCellPopulation->Update();
140 
141  unsigned num_cells = pCellPopulation->GetNumRealCells();
142 
143  // Store a map between cells numbered 1 to n and location indices
144  std::map<unsigned,unsigned> local_cell_id_location_index_map;
145 
146  unsigned local_cell_id = 0;
147  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
148  cell_iter != pCellPopulation->End();
149  ++cell_iter)
150  {
151  local_cell_id_location_index_map[pCellPopulation->GetLocationIndexUsingCell(*cell_iter)] = local_cell_id;
152  local_cell_id++;
153  }
154  assert(local_cell_id = num_cells+1);
155 
156  // Iterate over cells and calculate the adjacency matrix (stored as a long vector)
157  std::vector<double> adjacency_matrix(num_cells*num_cells);
158  for (unsigned i=0; i<num_cells*num_cells; i++)
159  {
160  adjacency_matrix[i] = 0;
161  }
162 
163  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
164  cell_iter != pCellPopulation->End();
165  ++cell_iter)
166  {
167  // Determine whether this cell is labelled
168  bool cell_is_labelled = cell_iter->template HasCellProperty<CellLabel>();
169 
170  // Get the location index corresponding to this cell
171  unsigned index = pCellPopulation->GetLocationIndexUsingCell(*cell_iter);
172 
173  // Get the set of neighbouring location indices
174  std::set<unsigned> neighbour_indices = pCellPopulation->GetNeighbouringLocationIndices(*cell_iter);
175 
176  // If this cell has any neighbours (as defined by mesh/population/interaction distance)...
177  if (!neighbour_indices.empty())
178  {
179  unsigned local_cell_index = local_cell_id_location_index_map[index];
180 
181  for (std::set<unsigned>::iterator neighbour_iter = neighbour_indices.begin();
182  neighbour_iter != neighbour_indices.end();
183  ++neighbour_iter)
184  {
185  // If both cell_iter and p_neighbour_cell are not labelled, then set type_of_link to 1
186  unsigned type_of_link = 1;
187 
188  // Determine whether this neighbour is labelled
189  CellPtr p_neighbour_cell = pCellPopulation->GetCellUsingLocationIndex(*neighbour_iter);
190  bool neighbour_is_labelled = p_neighbour_cell->template HasCellProperty<CellLabel>();
191 
192  if (cell_is_labelled != neighbour_is_labelled)
193  {
194  // Here cell_iter is labelled but p_neighbour_cell is not, or vice versa, so set type_of_link to 3
195  type_of_link = 3;
196  }
197  else if (cell_is_labelled)
198  {
199  // Here both cell_iter and p_neighbour_cell are labelled, so set type_of_link to 2
200  type_of_link = 2;
201  }
202 
203  unsigned local_neighbour_index = local_cell_id_location_index_map[*neighbour_iter];
204  adjacency_matrix[local_cell_index + num_cells*local_neighbour_index] = type_of_link;
205  adjacency_matrix[num_cells*local_cell_index + local_neighbour_index] = type_of_link;
206  }
207  }
208  }
209 
210  // Output the number of cells and the elements of the adjacency matrix
211  *this->mpOutStream << num_cells << "\t";
212  for (unsigned i=0; i<num_cells*num_cells; i++)
213  {
214  *this->mpOutStream << adjacency_matrix[i] << "\t";
215  }
216 }
217 
218 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
220 {
221 }
222 
223 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
225 {
226  VisitAnyPopulation(pCellPopulation);
227 }
228 
229 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
231 {
232  VisitAnyPopulation(pCellPopulation);
233 }
234 
235 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
237 {
238  VisitAnyPopulation(pCellPopulation);
239 }
240 
241 // Explicit instantiation
248 
250 // Declare identifier for the serializer
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
unsigned GetLocationIndexUsingCell(CellPtr pCell)
virtual std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)=0
void VisitAnyPopulation(AbstractCellPopulation< SPACE_DIM, SPACE_DIM > *pCellPopulation)
virtual std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
virtual void Update(bool hasHadBirthsOrDeaths=true)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual void Update(bool hasHadBirthsOrDeaths=true)=0
virtual void Visit(MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM > *pCellPopulation)