27 #include <boost/algorithm/string/predicate.hpp>
28 #include <boost/lexical_cast.hpp>
29 #include <boost/property_tree/ptree.hpp>
30 #include <boost/property_tree/xml_parser.hpp>
39 shared_ptr<Mesh> MBMBuilder::Build(
const MeshState& mesh_state)
41 unsigned int num_chem = CalculateNumChemicals(mesh_state);
42 m_mesh = make_shared<Mesh>(num_chem);
44 BuildNodes(mesh_state);
45 BuildCells(mesh_state);
46 BuildBoundaryPolygon(mesh_state);
47 BuildWalls(mesh_state);
48 ConnectCellsToWalls(mesh_state);
50 m_mesh->ConstructNeighborList(m_mesh->GetBoundaryPolygon());
51 m_mesh->UpdateNodeOwningNeighbors(m_mesh->GetBoundaryPolygon());
52 for (
auto const& cell : m_mesh->GetCells()) {
53 m_mesh->ConstructNeighborList(cell);
54 m_mesh->UpdateNodeOwningNeighbors(cell);
62 void MBMBuilder::BuildBoundaryPolygon(
const MeshState& mesh_state)
65 vector<unsigned int> bp_nodes_id(bpni.begin(), bpni.end());
66 auto new_bp = m_mesh->BuildBoundaryPolygon(bp_nodes_id);
68 new_bp->Cell::ReadPtree(empty_pt);
71 void MBMBuilder::BuildCells(
const MeshState& mesh_state)
73 unsigned int num_chem = m_mesh->GetNumChemicals();
76 for (
size_t cell_idx = 0; cell_idx < mesh_state.
GetNumCells(); ++cell_idx) {
78 const int cell_id = mesh_state.
GetCellID(cell_idx);
80 vector<unsigned int> cell_nodes_id(cni.begin(), cni.end());
81 auto new_cell = m_mesh->BuildCell(cell_id, cell_nodes_id);
84 new_cell->SetGeoDirty();
89 attributes_pt.put(
"boundary", cell_attr.Get<
string>(cell_idx,
"boundary_type"));
90 attributes_pt.put(
"dead", static_cast<bool>(cell_attr.Get<
int>(cell_idx,
"dead")));
91 attributes_pt.put(
"division_count", cell_attr.Get<
int>(cell_idx,
"div_counter"));
92 attributes_pt.put(
"fixed", cell_attr.Get<
int>(cell_idx,
"fixed"));
93 attributes_pt.put(
"solute", cell_attr.Get<
double>(cell_idx,
"solute"));
94 attributes_pt.put(
"stiffness", cell_attr.Get<
double>(cell_idx,
"stiffness"));
95 attributes_pt.put(
"target_area", cell_attr.Get<
double>(cell_idx,
"target_area"));
96 attributes_pt.put(
"target_length", cell_attr.Get<
double>(cell_idx,
"target_length"));
97 attributes_pt.put(
"type", cell_attr.Get<
int>(cell_idx,
"type"));
98 for (
size_t chem_idx = 0; chem_idx < num_chem; ++chem_idx) {
99 const string chem_name = string(
"chem_") + boost::lexical_cast<
string>(chem_idx);
100 new_cell->SetChemical(chem_idx, cell_attr.Get<
double>(cell_idx, chem_name));
101 attributes_pt.add(
"chemical_array.chemical", cell_attr.Get<
double>(cell_idx, chem_name));
103 new_cell->CellAttributes::ReadPtree(attributes_pt);
107 void MBMBuilder::BuildNodes(
const MeshState& mesh_state)
110 for (
size_t node_idx = 0; node_idx < mesh_state.
GetNumNodes(); ++node_idx) {
112 const int node_id = mesh_state.
GetNodeID(node_idx);
113 array<double,3> node_xyz {{mesh_state.
GetNodeX(node_idx), mesh_state.
GetNodeY(node_idx), 0.0}};
117 auto new_node = m_mesh->BuildNode(node_id, node_xyz, node_at_boundary);
125 void MBMBuilder::BuildWalls(
const MeshState& mesh_state)
127 auto& mesh_cells = m_mesh->GetCells();
128 auto& mesh_nodes = m_mesh->GetNodes();
129 for (
size_t wall_idx = 0; wall_idx < mesh_state.
GetNumWalls(); ++wall_idx) {
130 const int wall_id = mesh_state.
GetWallID(wall_idx);
131 const pair<int,int> nid = mesh_state.GetWallNodes(wall_idx);
132 const pair<int,int> cid = mesh_state.GetWallCells(wall_idx);
133 auto n1 = mesh_nodes[nid.first];
134 auto n2 = mesh_nodes[nid.second];
135 auto c1 = (cid.first != -1) ? mesh_cells[cid.first] : m_mesh->GetBoundaryPolygon();
136 auto c2 = (cid.second != -1) ? mesh_cells[cid.second] : m_mesh->GetBoundaryPolygon();
138 auto new_wall = m_mesh->BuildWall(wall_id, n1, n2, c1, c2);
143 attributes_pt.put(
"rest_length", wall_attr.Get<
double>(wall_idx,
"rest_length"));
144 attributes_pt.put(
"rest_length_init", wall_attr.Get<
double>(wall_idx,
"rest_length_init"));
145 attributes_pt.put(
"strength", wall_attr.Get<
double>(wall_idx,
"strength"));
146 attributes_pt.put(
"type", wall_attr.Get<
string>(wall_idx,
"type"));
152 size_t num_chem = m_mesh->GetNumChemicals();
153 for (
size_t chem_idx = 0; chem_idx < num_chem; ++chem_idx) {
154 const string trans_1_name = string(
"trans_1_chem_") + boost::lexical_cast<
string>(chem_idx);
155 const string trans_2_name = string(
"trans_2_chem_") + boost::lexical_cast<
string>(chem_idx);
156 new_wall->SetTransporters1(chem_idx, wall_attr.Get<
double>(wall_idx, trans_1_name));
157 new_wall->SetTransporters2(chem_idx, wall_attr.Get<
double>(wall_idx, trans_2_name));
158 attributes_pt.add(
"transporter1_array.transporter1", wall_attr.Get<
double>(wall_idx, trans_1_name));
159 attributes_pt.add(
"transporter2_array.transporter2", wall_attr.Get<
double>(wall_idx, trans_2_name));
161 new_wall->WallAttributes::ReadPtree(attributes_pt);
165 unsigned int MBMBuilder::CalculateNumChemicals(
const MeshState& mesh_state)
171 vector<string> cell_chems;
172 for_each(cell_attr_d.begin(), cell_attr_d.end(), [&](
string attr_name){
174 if(boost::starts_with(attr_name,
"chem_")) {
175 cell_chems.push_back(attr_name);
182 for (
size_t chem_idx = 0; chem_idx < num_chem; ++chem_idx) {
183 const string chem_name = string(
"chem_") + boost::lexical_cast<
string>(chem_idx);
184 if (find(cell_chems.begin(), cell_chems.end(), chem_name) == cell_chems.end())
185 throw runtime_error(
"Could not find chemical: \'" + chem_name +
"\'");
191 void MBMBuilder::ConnectCellsToWalls(
const MeshState& mesh_state)
196 auto& mesh_cells = m_mesh->GetCells();
197 auto& mesh_walls = m_mesh->GetWalls();
199 for (
size_t cell_idx = 0; cell_idx < mesh_state.
GetNumCells(); ++cell_idx) {
200 const int cell_id = mesh_state.
GetCellID(cell_idx);
201 vector<int> cell_walls = mesh_state.
GetCellWalls(cell_idx);
203 for (
const int wall_id : cell_walls) {
204 auto wall_it = find_if(mesh_walls.begin(), mesh_walls.end(), [wall_id](
Wall* w) {
205 return static_cast<unsigned int>(wall_id) == w->GetIndex();
207 assert((wall_it != mesh_walls.end()) &&
"Cannot find the cell wall!");
208 mesh_cells[cell_id]->GetWalls().push_back(*wall_it);
215 for (
const int wall_id : bp_walls) {
216 auto wall_it = find_if(mesh_walls.begin(), mesh_walls.end(), [wall_id](
Wall* w) {
217 return static_cast<unsigned int>(wall_id) == w->GetIndex();
219 assert((wall_it != mesh_walls.end()) &&
"Cannot find the boundary wall!");
220 m_mesh->GetBoundaryPolygon()->GetWalls().push_back(*wall_it);
223 for (
auto &wall : m_mesh->GetWalls()) {
224 m_mesh->UpdateNodeOwningWalls(wall);
double GetNodeY(size_t node_idx) const
Returns the y coordinate of a particular node.
int GetWallID(size_t wall_idx) const
Returns the ID of a particular wall.
Interface for MBMBBuilder.
size_t GetNumCells() const
Returns the number of cells in the mesh.
double GetNodeX(size_t node_idx) const
Returns the x coordinate of a particular node.
int GetCellID(size_t cell_idx) const
Returns the ID of a particular cell.
T Get(size_t index, const std::string &name) const
Returns the value of a named attribute.
Namespace for the core simulator.
std::vector< int > GetCellNodes(size_t cell_idx) const
Returns the IDs of the nodes that form the polygon of a particular cell.
AttributeContainer & WallAttributeContainer()
Adds a new named attribute of type T for the nodes.
AttributeContainer & NodeAttributeContainer()
Adds a new named attribute of type T for the nodes.
int GetNodeID(size_t node_idx) const
Returns the ID of a particular node.
std::vector< std::string > GetNames() const
Returns a vector containing the names of attributes of type T.
std::vector< int > GetBoundaryPolygonWalls() const
Returns the IDs of the walls that form the boundary polygon of the tissue.
Contains the state of the whole Mesh at a given simulation step.
std::vector< int > GetBoundaryPolygonNodes() const
Returns the IDs of the nodes that form the boundary polygon of the tissue.
AttributeContainer & CellAttributeContainer()
Adds a new named attribute of type T for the nodes.
size_t GetNumNodes() const
Returns the number of nodes in the mesh.
std::vector< int > GetCellWalls(size_t cell_idx) const
Returns the IDs of walls of a particular cell.
size_t GetNumWalls() const
Returns the number of walls in the mesh.
A cell wall, runs between cell corner points and consists of wall elements.