27 #include <boost/optional.hpp>
28 #include <boost/property_tree/ptree.hpp>
38 using boost::optional;
42 std::shared_ptr<Mesh> PBMBuilder::Build(
const ptree& mesh_pt)
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");
49 unsigned int num_chem = cells_pt.get<
unsigned int>(
"chemical_count");
50 m_mesh = make_shared<Mesh>(num_chem);
57 BuildBoundaryPolygon(cells_pt);
58 assert((m_mesh->GetCells().size() == cells_pt.get<
unsigned int>(
"count")) &&
"CellCount does match with file!");
62 ConnectCellsToWalls(cells_pt);
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);
74 void PBMBuilder::BuildBoundaryPolygon(
const ptree& cells_pt)
76 const auto& boundary_pt = cells_pt.get_child(
"boundary_polygon");
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>());
84 auto boundary_polygon = m_mesh->BuildBoundaryPolygon(node_ids);
85 boundary_polygon->ReadPtree(boundary_pt);
89 void PBMBuilder::BuildCells(
const ptree& cells_pt)
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");
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>());
102 auto new_cell = m_mesh->BuildCell(
id, node_ids);
103 new_cell->ReadPtree(cell_pt);
107 void PBMBuilder::BuildNodes(
const ptree& nodes_pt)
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);
119 void PBMBuilder::BuildWalls(
const ptree& walls_pt)
121 optional<const ptree&> wall_array_pt = walls_pt.get_child_optional(
"wall_array");
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");
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();
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];
139 auto wall = m_mesh->BuildWall(wall_id, n1, n2, c1, c2);
140 wall->ReadPtree(wall_pt);
145 void PBMBuilder::ConnectCellsToWalls(
const ptree& cells_pt)
147 auto& mesh_cells = m_mesh->GetCells();
148 auto& mesh_walls = m_mesh->GetWalls();
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");
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();
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));
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();
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));
180 for (
auto &wall : m_mesh->GetWalls()) {
181 m_mesh->UpdateNodeOwningWalls(wall);
Namespace for the core simulator.
Interface for PBMBBuilder.
A cell wall, runs between cell corner points and consists of wall elements.