30 #include <boost/optional.hpp>
31 #include <boost/property_tree/ptree.hpp>
38 using boost::optional;
42 Tissue PtreeTissueBuilder::Build(
const ptree& pt)
46 tissue.m_mesh = BuildMesh(pt.get_child(
"mesh"));
47 tissue.m_cell_attributes = BuildAttributeStore(
49 pt.get_child(
"parameters.model.attributes.cell_attributes_array"),
50 pt.get_child(
"mesh.cells.cell_array"));
51 tissue.m_node_attributes = BuildAttributeStore(
53 pt.get_child(
"parameters.model.attributes.node_attributes_array"),
54 pt.get_child(
"mesh.nodes.node_array"));
55 tissue.m_wall_attributes = BuildAttributeStore(
57 pt.get_child(
"parameters.model.attributes.wall_attributes_array"),
58 pt.get_child(
"mesh.walls.wall_array"));
63 shared_ptr<AttributeStore> PtreeTissueBuilder::BuildAttributeStore(
64 const string& entity_id,
const ptree& index_pt,
const ptree& values_pt)
66 const auto as = make_shared<AttributeStore>(index_pt);
67 const auto id = entity_id +
".attributes";
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)));
74 for (
const auto& name : as->GetAttributeNames<
int>()) {
75 as->Container<
int>(name).push_back(pt2.get<
int>(name, as->GetDefaultValue<
int>(name)));
77 for (
const auto& name : as->GetAttributeNames<
bool>()) {
78 as->Container<
double>(name).push_back(pt2.get<
double>(name, as->GetDefaultValue<
double>(name)));
80 for (
const auto& name : as->GetAttributeNames<
string>()) {
81 as->Container<
string>(name).push_back(pt2.get<
string>(name, as->GetDefaultValue<
string>(name)));
88 shared_ptr<Mesh> PtreeTissueBuilder::BuildMesh(
const ptree& mesh_pt)
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");
95 unsigned int num_chem = cells_pt.get<
unsigned int>(
"chemical_count");
96 m_mesh = make_shared<Mesh>(num_chem);
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!");
107 BuildWalls(walls_pt);
108 ConnectCellsToWalls(cells_pt);
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);
120 void PtreeTissueBuilder::BuildBoundaryPolygon(
const ptree& cells_pt)
122 const auto& boundary_pt = cells_pt.get_child(
"boundary_polygon");
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>());
130 auto boundary_polygon = m_mesh->BuildBoundaryPolygon(node_ids);
131 boundary_polygon->ReadPtree(boundary_pt);
135 void PtreeTissueBuilder::BuildCells(
const ptree& cells_pt)
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");
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>());
148 auto new_cell = m_mesh->BuildCell(
id, node_ids);
149 new_cell->ReadPtree(cell_pt);
153 void PtreeTissueBuilder::BuildNodes(
const ptree& nodes_pt)
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);
165 void PtreeTissueBuilder::BuildWalls(
const ptree& walls_pt)
167 optional<const ptree&> wall_array_pt = walls_pt.get_child_optional(
"wall_array");
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");
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();
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];
185 auto wall = m_mesh->BuildWall(wall_id, n1, n2, c1, c2);
186 wall->ReadPtree(wall_pt);
191 void PtreeTissueBuilder::ConnectCellsToWalls(
const ptree& cells_pt)
193 auto& mesh_cells = m_mesh->GetCells();
194 auto& mesh_walls = m_mesh->GetWalls();
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");
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();
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));
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();
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));
226 for (
auto &wall : m_mesh->GetWalls()) {
227 m_mesh->UpdateNodeOwningWalls(wall);
Interface of AttributeStore.
Tissue data with mesh, cell attributes, node attributes and wall attributes.
Namespace for the core simulator.
Interface for PBMBBuilder.
Tissue components used during model execution.