VPTissue Reference Manual
NodeInserter.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 "NodeInserter.h"
21 
22 #include "bio/Cell.h"
23 #include "bio/Edge.h"
24 #include "bio/Node.h"
25 #include "bio/Mesh.h"
26 #include "bio/Wall.h"
27 #include "sim/Sim.h"
28 #include "util/misc/Exception.h"
29 #include "util/misc/log_debug.h"
30 
31 using namespace std;
32 using namespace boost::property_tree;
33 using namespace SimPT_Sim;
34 using namespace SimPT_Sim::Util;
35 
36 namespace SimPT_Sim{
37 
38 NodeInserter::NodeInserter()
39  : m_mesh(nullptr), m_target_node_distance(0.0), m_yielding_threshold(0.0)
40 {
41 }
42 
44  : m_mesh(nullptr), m_target_node_distance(0.0), m_yielding_threshold(0.0)
45 {
46  Initialize(cd);
47 }
48 
49 
51 {
52  try {
53  assert( cd.Check() && "CoreData not ok.");
54  m_cd = cd;
55  m_mesh = m_cd.m_mesh.get();
56 
57  m_target_node_distance = m_cd.m_parameters->get<double>("cell_mechanics.target_node_distance");
58  m_yielding_threshold = m_cd.m_parameters->get<double>("cell_mechanics.yielding_threshold");
59  }
60  catch(exception& e) {
61  const string here = string(VL_HERE) + " exception:\n";
62  throw Exception(here + e.what());
63  }
64 }
65 
66 void NodeInserter::InsertNode(Edge& edge)
67 {
68  Wall *wall = m_mesh->FindWall(edge);
69 
70  // Construct a new node in the middle of the edge
71  const array<double, 3> pos = (*edge.GetFirst() + *edge.GetSecond()) / 2.0;
72  auto new_node = m_mesh->BuildNode(pos, m_mesh->IsAtBoundary(&edge));
73  new_node->SetFixed(edge.GetFirst()->IsFixed() && edge.GetSecond()->IsFixed());
74  new_node->SetSam(new_node->IsAtBoundary() &&
75  (edge.GetFirst()->IsSam() || edge.GetSecond()->IsSam()));
76 
77  UpdateNeighbors(edge, new_node);
78  m_mesh->GetNodeOwningWalls(new_node) = { wall };
79 }
80 
82 {
83  unsigned int insert_count = 0U;
84  const auto& walls = m_mesh->GetWalls();
85 
86  for (const auto& wall : walls) {
87  if ( wall->GetC1()->IsFixed() || wall->GetC2()->IsFixed()) {
88  continue;
89  }
90  vector<Edge> edges = wall->GetEdges();
91  for (auto edge : edges) {
92  const double l = Norm(*edge.GetFirst() - *edge.GetSecond());
93  if (l > m_yielding_threshold * m_target_node_distance) {
94  InsertNode(edge);
95  insert_count++;
96  }
97  }
98  }
99 
100  return insert_count;
101 }
102 
103 void NodeInserter::UpdateNeighbors(Edge& edge, Node* new_node)
104 {
105  list<NeighborNodes> owners;
106 
107  // Lambdas to compare neighbors.
108  auto cmp = [](const NeighborNodes& n1, const NeighborNodes& n2) {
109  return n1.GetCell()->GetIndex() < n2.GetCell()->GetIndex();
110  };
111  auto eql = [](const NeighborNodes& n1, const NeighborNodes& n2) {
112  return n1.GetCell()->GetIndex() == n2.GetCell()->GetIndex();
113  };
114 
115  // Push all cells owning the two nodes of the divided edges onto a list.
116  auto& owners_first = m_mesh->GetNodeOwningNeighbors(edge.GetFirst());
117  copy(owners_first.begin(), owners_first.end(), back_inserter(owners));
118  auto& owners_second = m_mesh->GetNodeOwningNeighbors(edge.GetSecond());
119  copy(owners_second.begin(), owners_second.end(), back_inserter(owners));
120  owners.sort(cmp);
121 
122  // The duplicates in this list indicate cells owning this edge.
123  auto c = owners.begin();
124  while (c != owners.end()) {
125  c = adjacent_find(c, owners.end(), eql);
126 
127  if (c != owners.end()) {
128  m_mesh->AddNodeToCell(c->GetCell(), new_node, edge.GetFirst(), edge.GetSecond());
129  } else {
130  break;
131  }
132  c++;
133  }
134 
135  // Repair neighborhood lists in a second loop, to make sure it is up to date
136  while (c != owners.end()) {
137  c = adjacent_find(c, owners.end(), eql);
138  // repair neighborhood lists of cell and Wall lists
139  if (!c->GetCell()->IsBoundaryPolygon()) {
140  m_mesh->ConstructNeighborList(c->GetCell());
141  }
142  c++;
143  }
144 }
145 
146 } // namespace
void Initialize(const CoreData &cd)
Initializes based on values in property tree.
Core data with mesh, parameters, random engine and time data.
Definition: CoreData.h:38
bool IsAtBoundary(const Edge *e) const
True iff the edge is on the mesh boundary.
Definition: Mesh.cpp:636
STL namespace.
Node in cell wall.
Definition: Node.h:39
std::list< Wall * > & GetNodeOwningWalls(Node *n)
The walls that contain the given node somewhere on the wall.
Definition: Mesh.h:130
Cell * GetCell() const
Return the cell of this Neighbor pair.
Namespace for miscellaneous utilities.
Definition: PTreeFile.cpp:44
NodeInserter()
Straight initialization of empty object.
Extremely simple Exception root class.
Definition: Exception.h:28
Namespace for the core simulator.
void ConstructNeighborList(Cell *cell)
Constructs neighbor list by looping over walls and registering adjoining cell for that wall...
Definition: Mesh.cpp:252
An Edge connects two nodes and is ambidextrous.
Definition: Edge.h:31
Interface for Cell.
Macro defs for debug and logging.
Structure of neighboring nodes: two neighboring nodes from standpoint of a given cell with an orderin...
Definition: NeighborNodes.h:34
void AddNodeToCell(Cell *c, Node *n, Node *nb1, Node *nb2)
Add node to cell between existing neighbor nodes.
Definition: Mesh.cpp:84
Node * GetFirst() const
Get the first node of the edge.
Definition: Edge.h:45
Sim, the actual simulator.
Interface for Node.
int GetIndex() const
Return the index.
Definition: Cell.h:76
std::list< NeighborNodes > & GetNodeOwningNeighbors(Node *n)
Get the neighbors associated with this node.
Definition: Mesh.h:124
Interface for Edge.
unsigned int InsertNodes()
Insert nodes in those edges that have been stretched.
Interface for NodeInserter.
Header file for Exception class.
Wall * FindWall(const Edge &edge) const
Find the wall including the edge.
Definition: Mesh.cpp:373
const std::vector< Wall * > & GetWalls() const
The walls of this mesh.
Definition: Mesh.h:148
A cell wall, runs between cell corner points and consists of wall elements.
Definition: Wall.h:48
bool Check() const
Verify all pointers non-null.
Definition: CoreData.h:53
Node * GetSecond() const
Get the second node of the edge.
Definition: Edge.h:51
Interface for Wall.
Interface for Mesh.