VPTissue Reference Manual
PtreeTissueBuilder.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "PtreeTissueBuilder.h"
21 
22 #include "AttributeStore.h"
23 #include "Cell.h"
24 #include "Mesh.h"
25 #include "Node.h"
26 #include "Tissue.h"
27 #include "Wall.h"
28 #include "WallType.h"
29 
30 #include <boost/optional.hpp>
31 #include <boost/property_tree/ptree.hpp>
32 #include <array>
33 #include <iostream>
34 #include <list>
35 
36 using namespace std;
37 using namespace boost::property_tree;
38 using boost::optional;
39 
40 namespace SimPT_Sim {
41 
42 Tissue PtreeTissueBuilder::Build(const ptree& pt)
43 {
44  Tissue tissue;
45 
46  tissue.m_mesh = BuildMesh(pt.get_child("mesh"));
47  tissue.m_cell_attributes = BuildAttributeStore(
48  "cell",
49  pt.get_child("parameters.model.attributes.cell_attributes_array"),
50  pt.get_child("mesh.cells.cell_array"));
51  tissue.m_node_attributes = BuildAttributeStore(
52  "node",
53  pt.get_child("parameters.model.attributes.node_attributes_array"),
54  pt.get_child("mesh.nodes.node_array"));
55  tissue.m_wall_attributes = BuildAttributeStore(
56  "wall",
57  pt.get_child("parameters.model.attributes.wall_attributes_array"),
58  pt.get_child("mesh.walls.wall_array"));
59 
60  return tissue;
61 }
62 
63 shared_ptr<AttributeStore> PtreeTissueBuilder::BuildAttributeStore(
64  const string& entity_id, const ptree& index_pt, const ptree& values_pt)
65 {
66  const auto as = make_shared<AttributeStore>(index_pt);
67  const auto id = entity_id + ".attributes";
68 
69  for(auto it = values_pt.begin(); it != values_pt.end(); it++){
70  const auto pt2 = it->second.get_child(id);
71  for (const auto& name : as->GetAttributeNames<bool>()) {
72  as->Container<bool>(name).push_back(pt2.get<bool>(name, as->GetDefaultValue<bool>(name)));
73  }
74  for (const auto& name : as->GetAttributeNames<int>()) {
75  as->Container<int>(name).push_back(pt2.get<int>(name, as->GetDefaultValue<int>(name)));
76  }
77  for (const auto& name : as->GetAttributeNames<bool>()) {
78  as->Container<double>(name).push_back(pt2.get<double>(name, as->GetDefaultValue<double>(name)));
79  }
80  for (const auto& name : as->GetAttributeNames<string>()) {
81  as->Container<string>(name).push_back(pt2.get<string>(name, as->GetDefaultValue<string>(name)));
82  }
83  }
84 
85  return as;
86 }
87 
88 shared_ptr<Mesh> PtreeTissueBuilder::BuildMesh(const ptree& mesh_pt)
89 {
90  auto cells_pt = mesh_pt.get_child("cells");
91  const auto& nodes_pt = mesh_pt.get_child("nodes");
92  const auto& walls_pt = mesh_pt.get_child("walls");
93 
94  // Set up empty mesh.
95  unsigned int num_chem = cells_pt.get<unsigned int>("chemical_count");
96  m_mesh = make_shared<Mesh>(num_chem);
97 
98  // Nodes
99  BuildNodes(nodes_pt);
100 
101  // Cells
102  BuildCells(cells_pt);
103  BuildBoundaryPolygon(cells_pt);
104  assert((m_mesh->GetCells().size() == cells_pt.get<unsigned int>("count")) && "CellCount does match with file!");
105 
106  // Allocate Walls (we need to have read the cells before constructing walls)
107  BuildWalls(walls_pt);
108  ConnectCellsToWalls(cells_pt);
109 
110  m_mesh->ConstructNeighborList(m_mesh->GetBoundaryPolygon());
111  m_mesh->UpdateNodeOwningNeighbors(m_mesh->GetBoundaryPolygon());
112  for (auto cell : m_mesh->GetCells()) {
113  m_mesh->ConstructNeighborList(cell);
114  m_mesh->UpdateNodeOwningNeighbors(cell);
115  }
116 
117  return m_mesh;
118 }
119 
120 void PtreeTissueBuilder::BuildBoundaryPolygon(const ptree& cells_pt)
121 {
122  const auto& boundary_pt = cells_pt.get_child("boundary_polygon");
123  {
124  vector<unsigned int> node_ids;
125  auto const& node_array_pt = boundary_pt.get_child("node_array");
126  for (auto const& node_v : node_array_pt) {
127  auto const& node_pt = node_v.second;
128  node_ids.push_back(node_pt.get_value<unsigned int>());
129  }
130  auto boundary_polygon = m_mesh->BuildBoundaryPolygon(node_ids);
131  boundary_polygon->ReadPtree(boundary_pt);
132  }
133 }
134 
135 void PtreeTissueBuilder::BuildCells(const ptree& cells_pt)
136 {
137  for (auto cell_v : cells_pt.get_child("cell_array")) {
138  auto cell_pt = cell_v.second;
139  unsigned int id = cell_pt.get<unsigned int>("id");
140 
141  vector<unsigned int> node_ids;
142  auto const& node_array_pt = cell_pt.get_child("node_array");
143  for (auto const& node_v : node_array_pt) {
144  auto const& node_pt = node_v.second;
145  node_ids.push_back(node_pt.get_value<unsigned int>());
146  }
147 
148  auto new_cell = m_mesh->BuildCell(id, node_ids);
149  new_cell->ReadPtree(cell_pt);
150  }
151 }
152 
153 void PtreeTissueBuilder::BuildNodes(const ptree& nodes_pt)
154 {
155  for (const auto& node_v : nodes_pt.get_child("node_array")) {
156  const ptree& node_pt = node_v.second;
157  unsigned int id = node_pt.get<unsigned int>("id");
158  array<double, 3> arr {{ node_pt.get<double>("x"), node_pt.get<double>("y"), 0.0 }};
159  const bool at_boundary = node_pt.get<bool>("boundary");
160  auto new_node = m_mesh->BuildNode(id, arr, at_boundary);
161  new_node->ReadPtree(node_pt);
162  }
163 }
164 
165 void PtreeTissueBuilder::BuildWalls(const ptree& walls_pt)
166 {
167  optional<const ptree&> wall_array_pt = walls_pt.get_child_optional("wall_array");
168  if (wall_array_pt) {
169  for (const auto& wall_v : *wall_array_pt) {
170  const ptree& wall_pt = wall_v.second;
171  const unsigned int wall_id = wall_pt.get<unsigned int>("id");
172 
173  auto& mesh_cells = m_mesh->GetCells();
174  int const c1_id = wall_pt.get<int>("c1");
175  int const c2_id = wall_pt.get<int>("c2");
176  auto c1 = (c1_id != -1) ? mesh_cells[c1_id] : m_mesh->GetBoundaryPolygon();
177  auto c2 = (c2_id != -1) ? mesh_cells[c2_id] : m_mesh->GetBoundaryPolygon();
178 
179  auto& mesh_nodes = m_mesh->GetNodes();
180  unsigned int const n1_id = wall_pt.get<unsigned int>("n1");
181  unsigned int const n2_id = wall_pt.get<unsigned int>("n2");
182  auto n1 = mesh_nodes[n1_id];
183  auto n2 = mesh_nodes[n2_id];
184 
185  auto wall = m_mesh->BuildWall(wall_id, n1, n2, c1, c2);
186  wall->ReadPtree(wall_pt);
187  }
188  }
189 }
190 
191 void PtreeTissueBuilder::ConnectCellsToWalls(const ptree& cells_pt)
192 {
193  auto& mesh_cells = m_mesh->GetCells();
194  auto& mesh_walls = m_mesh->GetWalls();
195 
196  const ptree& cell_array_pt = cells_pt.get_child("cell_array");
197  for (const auto & cell_v : cell_array_pt) {
198  const unsigned int id = cell_v.second.get<unsigned int>("id");
199  optional<const ptree&> wall_array_pt = cell_v.second.get_child_optional("wall_array");
200  if (wall_array_pt) {
201  for (const auto& wall_v : *wall_array_pt) {
202  const unsigned int w_id = wall_v.second.get_value<unsigned int>();
203  const auto eql = [w_id](Wall* w) {
204  return w_id == w->GetIndex();
205  };
206  auto it = find_if(mesh_walls.begin(), mesh_walls.end(), eql);
207  assert((it != mesh_walls.end()) && "Cannot find the cell wall!");
208  mesh_cells[id]->GetWalls().push_back((*it));
209  }
210  }
211  }
212 
213  optional<const ptree&> bp_wall_array_pt = cells_pt.get_child_optional("boundary_polygon.wall_array");
214  if (bp_wall_array_pt) {
215  for (const auto& wall_v : *bp_wall_array_pt) {
216  const unsigned int w_id = wall_v.second.get_value<unsigned int>();
217  const auto eql = [w_id](Wall* w) {
218  return w_id == w->GetIndex();
219  };
220  auto it = find_if(mesh_walls.begin(), mesh_walls.end(), eql);
221  assert((it != mesh_walls.end()) && "Cannot find the boundary wall!");
222  m_mesh->GetBoundaryPolygon()->GetWalls().push_back((*it));
223  }
224  }
225 
226  for (auto &wall : m_mesh->GetWalls()) {
227  m_mesh->UpdateNodeOwningWalls(wall);
228  }
229 }
230 
231 } // namespace
Interface of AttributeStore.
Tissue data with mesh, cell attributes, node attributes and wall attributes.
Definition: Tissue.h:32
STL namespace.
Definition of WallType.
Namespace for the core simulator.
Interface for Cell.
Interface for PBMBBuilder.
Interface for Node.
Tissue components used during model execution.
Interface for Wall.
Interface for Mesh.