VPTissue Reference Manual
PBMBuilder.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 "PBMBuilder.h"
21 
22 #include "Cell.h"
23 #include "Mesh.h"
24 #include "Node.h"
25 #include "WallType.h"
26 
27 #include <boost/optional.hpp>
28 #include <boost/property_tree/ptree.hpp>
29 #include <array>
30 #include <iostream>
31 #include <list>
32 
33 namespace SimPT_Sim { class Wall; }
34 
35 using namespace std;
36 using namespace SimPT_Sim;
37 using namespace boost::property_tree;
38 using boost::optional;
39 
40 namespace SimPT_Sim {
41 
42 std::shared_ptr<Mesh> PBMBuilder::Build(const ptree& mesh_pt)
43 {
44  auto cells_pt = mesh_pt.get_child("cells");
45  const auto& nodes_pt = mesh_pt.get_child("nodes");
46  const auto& walls_pt = mesh_pt.get_child("walls");
47 
48  // Set up empty mesh.
49  unsigned int num_chem = cells_pt.get<unsigned int>("chemical_count");
50  m_mesh = make_shared<Mesh>(num_chem);
51 
52  // Nodes
53  BuildNodes(nodes_pt);
54 
55  // Cells
56  BuildCells(cells_pt);
57  BuildBoundaryPolygon(cells_pt);
58  assert((m_mesh->GetCells().size() == cells_pt.get<unsigned int>("count")) && "CellCount does match with file!");
59 
60  // Allocate Walls (we need to have read the cells before constructing walls)
61  BuildWalls(walls_pt);
62  ConnectCellsToWalls(cells_pt);
63 
64  m_mesh->ConstructNeighborList(m_mesh->GetBoundaryPolygon());
65  m_mesh->UpdateNodeOwningNeighbors(m_mesh->GetBoundaryPolygon());
66  for (auto cell : m_mesh->GetCells()) {
67  m_mesh->ConstructNeighborList(cell);
68  m_mesh->UpdateNodeOwningNeighbors(cell);
69  }
70 
71  return m_mesh;
72 }
73 
74 void PBMBuilder::BuildBoundaryPolygon(const ptree& cells_pt)
75 {
76  const auto& boundary_pt = cells_pt.get_child("boundary_polygon");
77  {
78  vector<unsigned int> node_ids;
79  auto const& node_array_pt = boundary_pt.get_child("node_array");
80  for (auto const& node_v : node_array_pt) {
81  auto const& node_pt = node_v.second;
82  node_ids.push_back(node_pt.get_value<unsigned int>());
83  }
84  auto boundary_polygon = m_mesh->BuildBoundaryPolygon(node_ids);
85  boundary_polygon->ReadPtree(boundary_pt);
86  }
87 }
88 
89 void PBMBuilder::BuildCells(const ptree& cells_pt)
90 {
91  for (auto cell_v : cells_pt.get_child("cell_array")) {
92  auto cell_pt = cell_v.second;
93  unsigned int id = cell_pt.get<unsigned int>("id");
94 
95  vector<unsigned int> node_ids;
96  auto const& node_array_pt = cell_pt.get_child("node_array");
97  for (auto const& node_v : node_array_pt) {
98  auto const& node_pt = node_v.second;
99  node_ids.push_back(node_pt.get_value<unsigned int>());
100  }
101 
102  auto new_cell = m_mesh->BuildCell(id, node_ids);
103  new_cell->ReadPtree(cell_pt);
104  }
105 }
106 
107 void PBMBuilder::BuildNodes(const ptree& nodes_pt)
108 {
109  for (const auto& node_v : nodes_pt.get_child("node_array")) {
110  const ptree& node_pt = node_v.second;
111  unsigned int id = node_pt.get<unsigned int>("id");
112  array<double, 3> arr {{ node_pt.get<double>("x"), node_pt.get<double>("y"), 0.0 }};
113  const bool at_boundary = node_pt.get<bool>("boundary");
114  auto new_node = m_mesh->BuildNode(id, arr, at_boundary);
115  new_node->ReadPtree(node_pt);
116  }
117 }
118 
119 void PBMBuilder::BuildWalls(const ptree& walls_pt)
120 {
121  optional<const ptree&> wall_array_pt = walls_pt.get_child_optional("wall_array");
122  if (wall_array_pt) {
123  for (const auto& wall_v : *wall_array_pt) {
124  const ptree& wall_pt = wall_v.second;
125  const unsigned int wall_id = wall_pt.get<unsigned int>("id");
126 
127  auto& mesh_cells = m_mesh->GetCells();
128  int const c1_id = wall_pt.get<int>("c1");
129  int const c2_id = wall_pt.get<int>("c2");
130  auto c1 = (c1_id != -1) ? mesh_cells[c1_id] : m_mesh->GetBoundaryPolygon();
131  auto c2 = (c2_id != -1) ? mesh_cells[c2_id] : m_mesh->GetBoundaryPolygon();
132 
133  auto& mesh_nodes = m_mesh->GetNodes();
134  unsigned int const n1_id = wall_pt.get<unsigned int>("n1");
135  unsigned int const n2_id = wall_pt.get<unsigned int>("n2");
136  auto n1 = mesh_nodes[n1_id];
137  auto n2 = mesh_nodes[n2_id];
138 
139  auto wall = m_mesh->BuildWall(wall_id, n1, n2, c1, c2);
140  wall->ReadPtree(wall_pt);
141  }
142  }
143 }
144 
145 void PBMBuilder::ConnectCellsToWalls(const ptree& cells_pt)
146 {
147  auto& mesh_cells = m_mesh->GetCells();
148  auto& mesh_walls = m_mesh->GetWalls();
149 
150  const ptree& cell_array_pt = cells_pt.get_child("cell_array");
151  for (const auto & cell_v : cell_array_pt) {
152  const unsigned int id = cell_v.second.get<unsigned int>("id");
153  optional<const ptree&> wall_array_pt = cell_v.second.get_child_optional("wall_array");
154  if (wall_array_pt) {
155  for (const auto& wall_v : *wall_array_pt) {
156  const unsigned int w_id = wall_v.second.get_value<unsigned int>();
157  const auto eql = [w_id](Wall* w) {
158  return w_id == w->GetIndex();
159  };
160  auto it = find_if(mesh_walls.begin(), mesh_walls.end(), eql);
161  assert((it != mesh_walls.end()) && "Cannot find the cell wall!");
162  mesh_cells[id]->GetWalls().push_back((*it));
163  }
164  }
165  }
166 
167  optional<const ptree&> bp_wall_array_pt = cells_pt.get_child_optional("boundary_polygon.wall_array");
168  if (bp_wall_array_pt) {
169  for (const auto& wall_v : *bp_wall_array_pt) {
170  const unsigned int w_id = wall_v.second.get_value<unsigned int>();
171  const auto eql = [w_id](Wall* w) {
172  return w_id == w->GetIndex();
173  };
174  auto it = find_if(mesh_walls.begin(), mesh_walls.end(), eql);
175  assert((it != mesh_walls.end()) && "Cannot find the boundary wall!");
176  m_mesh->GetBoundaryPolygon()->GetWalls().push_back((*it));
177  }
178  }
179 
180  for (auto &wall : m_mesh->GetWalls()) {
181  m_mesh->UpdateNodeOwningWalls(wall);
182  }
183 }
184 
185 }
STL namespace.
Definition of WallType.
Namespace for the core simulator.
Interface for Cell.
Interface for PBMBBuilder.
Interface for Node.
A cell wall, runs between cell corner points and consists of wall elements.
Definition: Wall.h:48
Interface for Mesh.