Chaste  Release::2017.1
CellPopulationAdjacencyMatrixWriter.cpp
1 /*
2 
3 Copyright (c) 2005-2017, 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 
38 #include "AbstractCellPopulation.hpp"
39 #include "MeshBasedCellPopulation.hpp"
40 #include "CaBasedCellPopulation.hpp"
41 #include "NodeBasedCellPopulation.hpp"
42 #include "PottsBasedCellPopulation.hpp"
43 #include "VertexBasedCellPopulation.hpp"
44 
45 #include "CellLabel.hpp"
46 
47 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
49  : AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM>("cellpopulationadjacency.dat")
50 {
51 }
52 
53 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
55 {
56  // Make sure the cell population is updated
58  pCellPopulation->Update();
59 
60  unsigned num_cells = pCellPopulation->GetNumRealCells();
61 
62  // Store a map between cells numbered 1 to n and location indices
63  std::map<unsigned,unsigned> local_cell_id_location_index_map;
64 
65  unsigned local_cell_id = 0;
66  for (typename AbstractCellPopulation<SPACE_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
67  cell_iter != pCellPopulation->End();
68  ++cell_iter)
69  {
70  local_cell_id_location_index_map[pCellPopulation->GetLocationIndexUsingCell(*cell_iter)] = local_cell_id;
71  local_cell_id++;
72  }
73  assert(local_cell_id = num_cells+1);
74 
75  // Iterate over cells and calculate the adjacency matrix (stored as a long vector)
76  std::vector<double> adjacency_matrix(num_cells*num_cells);
77  for (unsigned i=0; i<num_cells*num_cells; i++)
78  {
79  adjacency_matrix[i] = 0;
80  }
81 
82  for (typename AbstractCellPopulation<SPACE_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
83  cell_iter != pCellPopulation->End();
84  ++cell_iter)
85  {
86  // Determine whether this cell is labelled
87  bool cell_is_labelled = cell_iter->template HasCellProperty<CellLabel>();
88 
89  // Get the location index corresponding to this cell
90  unsigned index = pCellPopulation->GetLocationIndexUsingCell(*cell_iter);
91 
92  // Get the set of neighbouring location indices
93  std::set<unsigned> neighbour_indices = pCellPopulation->GetNeighbouringLocationIndices(*cell_iter);
94 
95  // If this cell has any neighbours (as defined by mesh/population/interaction distance)...
96  if (!neighbour_indices.empty())
97  {
98  unsigned local_cell_index = local_cell_id_location_index_map[index];
99 
100  for (std::set<unsigned>::iterator neighbour_iter = neighbour_indices.begin();
101  neighbour_iter != neighbour_indices.end();
102  ++neighbour_iter)
103  {
104  // If both cell_iter and p_neighbour_cell are not labelled, then set type_of_link to 1
105  unsigned type_of_link = 1;
106 
107  // Determine whether this neighbour is labelled
108  CellPtr p_neighbour_cell = pCellPopulation->GetCellUsingLocationIndex(*neighbour_iter);
109  bool neighbour_is_labelled = p_neighbour_cell->template HasCellProperty<CellLabel>();
110 
111  if (cell_is_labelled != neighbour_is_labelled)
112  {
113  // Here cell_iter is labelled but p_neighbour_cell is not, or vice versa, so set type_of_link to 3
114  type_of_link = 3;
115  }
116  else if (cell_is_labelled)
117  {
118  // Here both cell_iter and p_neighbour_cell are labelled, so set type_of_link to 2
119  type_of_link = 2;
120  }
121 
122  unsigned local_neighbour_index = local_cell_id_location_index_map[*neighbour_iter];
123  adjacency_matrix[local_cell_index + num_cells*local_neighbour_index] = type_of_link;
124  adjacency_matrix[num_cells*local_cell_index + local_neighbour_index] = type_of_link;
125  }
126  }
127  }
128 
129  // Output the number of cells and the elements of the adjacency matrix
130  *this->mpOutStream << num_cells << "\t";
131  for (unsigned i=0; i<num_cells*num_cells; i++)
132  {
133  *this->mpOutStream << adjacency_matrix[i] << "\t";
134  }
135 }
136 
137 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
139 {
140  // Make sure the cell population is updated
142  pCellPopulation->Update();
143 
144  unsigned num_cells = pCellPopulation->GetNumRealCells();
145 
146  // Store a map between cells numbered 1 to n and location indices
147  std::map<unsigned,unsigned> local_cell_id_location_index_map;
148 
149  unsigned local_cell_id = 0;
150  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
151  cell_iter != pCellPopulation->End();
152  ++cell_iter)
153  {
154  local_cell_id_location_index_map[pCellPopulation->GetLocationIndexUsingCell(*cell_iter)] = local_cell_id;
155  local_cell_id++;
156  }
157  assert(local_cell_id = num_cells+1);
158 
159  // Iterate over cells and calculate the adjacency matrix (stored as a long vector)
160  std::vector<double> adjacency_matrix(num_cells*num_cells);
161  for (unsigned i=0; i<num_cells*num_cells; i++)
162  {
163  adjacency_matrix[i] = 0;
164  }
165 
166  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = pCellPopulation->Begin();
167  cell_iter != pCellPopulation->End();
168  ++cell_iter)
169  {
170  // Determine whether this cell is labelled
171  bool cell_is_labelled = cell_iter->template HasCellProperty<CellLabel>();
172 
173  // Get the location index corresponding to this cell
174  unsigned index = pCellPopulation->GetLocationIndexUsingCell(*cell_iter);
175 
176  // Get the set of neighbouring location indices
177  std::set<unsigned> neighbour_indices = pCellPopulation->GetNeighbouringLocationIndices(*cell_iter);
178 
179  // If this cell has any neighbours (as defined by mesh/population/interaction distance)...
180  if (!neighbour_indices.empty())
181  {
182  unsigned local_cell_index = local_cell_id_location_index_map[index];
183 
184  for (std::set<unsigned>::iterator neighbour_iter = neighbour_indices.begin();
185  neighbour_iter != neighbour_indices.end();
186  ++neighbour_iter)
187  {
188  // If both cell_iter and p_neighbour_cell are not labelled, then set type_of_link to 1
189  unsigned type_of_link = 1;
190 
191  // Determine whether this neighbour is labelled
192  CellPtr p_neighbour_cell = pCellPopulation->GetCellUsingLocationIndex(*neighbour_iter);
193  bool neighbour_is_labelled = p_neighbour_cell->template HasCellProperty<CellLabel>();
194 
195  if (cell_is_labelled != neighbour_is_labelled)
196  {
197  // Here cell_iter is labelled but p_neighbour_cell is not, or vice versa, so set type_of_link to 3
198  type_of_link = 3;
199  }
200  else if (cell_is_labelled)
201  {
202  // Here both cell_iter and p_neighbour_cell are labelled, so set type_of_link to 2
203  type_of_link = 2;
204  }
205 
206  unsigned local_neighbour_index = local_cell_id_location_index_map[*neighbour_iter];
207  adjacency_matrix[local_cell_index + num_cells*local_neighbour_index] = type_of_link;
208  adjacency_matrix[num_cells*local_cell_index + local_neighbour_index] = type_of_link;
209  }
210  }
211  }
212 
213  // Output the number of cells and the elements of the adjacency matrix
214  *this->mpOutStream << num_cells << "\t";
215  for (unsigned i=0; i<num_cells*num_cells; i++)
216  {
217  *this->mpOutStream << adjacency_matrix[i] << "\t";
218  }
219 }
220 
221 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
223 {
224 }
225 
226 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
228 {
229  VisitAnyPopulation(pCellPopulation);
230 }
231 
232 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
234 {
235  VisitAnyPopulation(pCellPopulation);
236 }
237 
238 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
240 {
241  VisitAnyPopulation(pCellPopulation);
242 }
243 
244 // Explicit instantiation
251 
253 // 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)