OGS
ProcessLib::LIE::PostProcessTool Class Referencefinal

Detailed Description

A tool for post-processing results from the LIE approach

The tool creates a new mesh containing duplicated fracture nodes to represent geometric discontinuities in visualization.

Definition at line 30 of file PostUtils.h.

#include <PostUtils.h>

Collaboration diagram for ProcessLib::LIE::PostProcessTool:
[legend]

Public Member Functions

 PostProcessTool (MeshLib::Mesh const &org_mesh, std::vector< int > const &vec_fracture_mat_IDs, std::vector< std::vector< MeshLib::Node * >> const &vec_vec_fracture_nodes, std::vector< std::vector< MeshLib::Element * >> const &vec_vec_fracture_matrix_elements, std::vector< std::pair< std::size_t, std::vector< int >>> const &vec_branch_nodeID_matIDs, std::vector< std::pair< std::size_t, std::vector< int >>> const &vec_junction_nodeID_matIDs)
 
MeshLib::Mesh const & getOutputMesh () const
 

Private Member Functions

template<typename T >
MeshLib::PropertyVector< T > * createProperty (MeshLib::PropertyVector< T > const &property)
 
template<typename T >
void copyPropertyValues (MeshLib::PropertyVector< T > const &source_property, MeshLib::PropertyVector< T > *const destination_property)
 
void calculateTotalDisplacement (unsigned const n_fractures, unsigned const n_junctions)
 

Private Attributes

MeshLib::Mesh const & _org_mesh
 
std::unique_ptr< MeshLib::Mesh_output_mesh
 
std::map< std::size_t, std::vector< std::size_t > > _map_dup_newNodeIDs
 

Constructor & Destructor Documentation

◆ PostProcessTool()

ProcessLib::LIE::PostProcessTool::PostProcessTool ( MeshLib::Mesh const &  org_mesh,
std::vector< int > const &  vec_fracture_mat_IDs,
std::vector< std::vector< MeshLib::Node * >> const &  vec_vec_fracture_nodes,
std::vector< std::vector< MeshLib::Element * >> const &  vec_vec_fracture_matrix_elements,
std::vector< std::pair< std::size_t, std::vector< int >>> const &  vec_branch_nodeID_matIDs,
std::vector< std::pair< std::size_t, std::vector< int >>> const &  vec_junction_nodeID_matIDs 
)

Definition at line 44 of file PostUtils.cpp.

54  : _org_mesh(org_mesh)
55 {
56  if (!org_mesh.getProperties().hasPropertyVector("displacement") ||
57  !org_mesh.getProperties().hasPropertyVector("displacement_jump1") ||
58  !org_mesh.getProperties().hasPropertyVector("levelset1"))
59  {
60  OGS_FATAL("The given mesh does not have relevant properties");
61  }
62 
63  // clone nodes and elements
64  std::vector<MeshLib::Node*> new_nodes(
65  MeshLib::copyNodeVector(org_mesh.getNodes()));
66  std::vector<MeshLib::Element*> new_eles(
67  MeshLib::copyElementVector(org_mesh.getElements(), new_nodes));
68 
69  // duplicate fracture nodes (two dup. nodes created at a branch)
70  for (auto const& vec_fracture_nodes : vec_vec_fracture_nodes)
71  {
72  for (auto const* org_node : vec_fracture_nodes)
73  {
74  auto duplicated_node =
75  new MeshLib::Node(org_node->getCoords(), new_nodes.size());
76  new_nodes.push_back(duplicated_node);
77  _map_dup_newNodeIDs[org_node->getID()].push_back(
78  duplicated_node->getID());
79  }
80  }
81  // at a junction, generate one more duplicated node (total 4 nodes)
82  for (auto& entry : vec_junction_nodeID_matIDs)
83  {
84  auto* org_node = org_mesh.getNode(entry.first);
85  auto duplicated_node =
86  new MeshLib::Node(org_node->getCoords(), new_nodes.size());
87  new_nodes.push_back(duplicated_node);
88  _map_dup_newNodeIDs[org_node->getID()].push_back(
89  duplicated_node->getID());
90  }
91 
92  // split elements using the new duplicated nodes
93  for (unsigned fracture_id = 0;
94  fracture_id < vec_vec_fracture_matrix_elements.size();
95  fracture_id++)
96  {
97  auto const frac_matid = vec_fracture_mat_IDs[fracture_id];
98  auto const& vec_fracture_matrix_elements =
99  vec_vec_fracture_matrix_elements[fracture_id];
100  auto const& vec_fracture_nodes = vec_vec_fracture_nodes[fracture_id];
101  auto prop_levelset = org_mesh.getProperties().getPropertyVector<double>(
102  "levelset" + std::to_string(fracture_id + 1));
103  for (auto const* org_e : vec_fracture_matrix_elements)
104  {
105  // only matrix elements
106  if (org_e->getDimension() != org_mesh.getDimension())
107  {
108  continue;
109  }
110 
111  auto const eid = org_e->getID();
112  // keep original if the element has levelset<=0
113  if ((*prop_levelset)[eid] <= 0)
114  {
115  continue;
116  }
117 
118  // replace fracture nodes with duplicated ones
119  MeshLib::Element* e = new_eles[eid];
120  for (unsigned i = 0; i < e->getNumberOfNodes(); i++)
121  {
122  const auto node_id = getNodeIndex(*e, i);
123  if (!includesNodeID(vec_fracture_nodes, node_id))
124  {
125  continue;
126  }
127 
128  // list of duplicated node IDs
129  auto itr = _map_dup_newNodeIDs.find(node_id);
130  if (itr == _map_dup_newNodeIDs.end())
131  {
132  continue;
133  }
134  const auto& dup_newNodeIDs = itr->second;
135 
136  // choose new node id
137  unsigned new_node_id = 0;
138  if (dup_newNodeIDs.size() == 1)
139  {
140  // non-intersected nodes
141  new_node_id = dup_newNodeIDs[0];
142  }
143  else if (dup_newNodeIDs.size() == 2)
144  {
145  // branch nodes
146  const auto& br_matids = getMaterialIdsForNode(
147  vec_branch_nodeID_matIDs, node_id);
148  auto const frac2_matid = BaseLib::findFirstNotEqualElement(
149  br_matids, frac_matid);
150  assert(frac2_matid);
151  auto const frac2_id =
152  BaseLib::findIndex(vec_fracture_mat_IDs, *frac2_matid);
153  assert(frac2_id != std::numeric_limits<std::size_t>::max());
154  auto prop_levelset2 =
155  org_mesh.getProperties().getPropertyVector<double>(
156  "levelset" + std::to_string(frac2_id + 1));
157  std::size_t pos = 0;
158  if ((*prop_levelset2)[eid] <= 0)
159  {
160  // index of this fracture
161  pos = BaseLib::findIndex(br_matids, frac_matid);
162  }
163  else if ((*prop_levelset2)[eid] > 0)
164  {
165  // index of the other fracture
166  pos = BaseLib::findIndex(br_matids, *frac2_matid);
167  }
168  assert(pos != std::numeric_limits<std::size_t>::max());
169  new_node_id = dup_newNodeIDs[pos];
170  }
171  else
172  {
173  // junction nodes
174  const auto& jct_matids = getMaterialIdsForNode(
175  vec_junction_nodeID_matIDs, node_id);
176  auto const frac2_matid = BaseLib::findFirstNotEqualElement(
177  jct_matids, frac_matid);
178  assert(frac2_matid);
179  auto const frac2_id =
180  BaseLib::findIndex(vec_fracture_mat_IDs, *frac2_matid);
181  assert(frac2_id != std::numeric_limits<std::size_t>::max());
182  auto prop_levelset2 =
183  org_mesh.getProperties().getPropertyVector<double>(
184  "levelset" + std::to_string(frac2_id + 1));
185 
186  //
187  if ((*prop_levelset2)[eid] <= 0)
188  {
189  // index of this frac
190  auto const pos =
191  BaseLib::findIndex(jct_matids, frac_matid);
192  assert(pos != std::numeric_limits<std::size_t>::max());
193  new_node_id = dup_newNodeIDs[pos];
194  }
195  else if ((*prop_levelset2)[eid] > 0)
196  {
197  // set the last duplicated node
198  new_node_id = dup_newNodeIDs.back();
199  }
200  }
201 
202  // replace node
203  e->setNode(i, new_nodes[new_node_id]);
204  }
205  }
206  }
207 
208  // new mesh
209  _output_mesh = std::make_unique<MeshLib::Mesh>(org_mesh.getName(),
210  new_nodes, new_eles);
211 
212  for (auto [name, property] : _org_mesh.getProperties())
213  {
214  if (auto p = dynamic_cast<MeshLib::PropertyVector<double>*>(property))
215  {
217  }
218  else if (auto p =
219  dynamic_cast<MeshLib::PropertyVector<float>*>(property))
220  {
222  }
223  else if (auto p = dynamic_cast<MeshLib::PropertyVector<int>*>(property))
224  {
226  }
227  else if (auto p =
228  dynamic_cast<MeshLib::PropertyVector<unsigned>*>(property))
229  {
231  }
232  else if (auto p =
233  dynamic_cast<MeshLib::PropertyVector<long>*>(property))
234  {
236  }
237  else if (auto p = dynamic_cast<MeshLib::PropertyVector<long long>*>(
238  property))
239  {
241  }
242  else if (auto p = dynamic_cast<MeshLib::PropertyVector<unsigned long>*>(
243  property))
244  {
246  }
247  else if (auto p =
249  property))
250  {
252  }
253  else if (auto p = dynamic_cast<MeshLib::PropertyVector<std::size_t>*>(
254  property))
255  {
257  }
258  else if (auto p =
259  dynamic_cast<MeshLib::PropertyVector<char>*>(property))
260  {
262  }
263  else
264  {
265  OGS_FATAL(
266  "Mesh property '{:s}' of unhandled data type '{:s}'. Please "
267  "check the data type of the mesh properties. The available "
268  "data types are:"
269  "\n\t double,"
270  "\n\t float,"
271  "\n\t int,"
272  "\n\t unsigned,"
273  "\n\t long,"
274  "\n\t long long,"
275  "\n\t unsigned long,"
276  "\n\t unsigned long long,"
277  "\n\t char.",
278  property->getPropertyName(),
279  typeid(*property).name());
280  }
281  }
282  calculateTotalDisplacement(vec_vec_fracture_nodes.size(),
283  vec_junction_nodeID_matIDs.size());
284 }
#define OGS_FATAL(...)
Definition: Error.h:26
virtual unsigned getNumberOfNodes() const =0
virtual void setNode(unsigned idx, Node *node)=0
Properties & getProperties()
Definition: Mesh.h:123
void copyPropertyValues(MeshLib::PropertyVector< T > const &source_property, MeshLib::PropertyVector< T > *const destination_property)
Definition: PostUtils.cpp:323
MeshLib::Mesh const & _org_mesh
Definition: PostUtils.h:57
std::map< std::size_t, std::vector< std::size_t > > _map_dup_newNodeIDs
Definition: PostUtils.h:59
void calculateTotalDisplacement(unsigned const n_fractures, unsigned const n_junctions)
Definition: PostUtils.cpp:376
MeshLib::PropertyVector< T > * createProperty(MeshLib::PropertyVector< T > const &property)
Definition: PostUtils.cpp:287
std::unique_ptr< MeshLib::Mesh > _output_mesh
Definition: PostUtils.h:58
std::optional< typename Container::value_type > findFirstNotEqualElement(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:271
std::size_t findIndex(Container const &container, typename Container::value_type const &element)
Definition: Algorithm.h:287
std::vector< Node * > copyNodeVector(const std::vector< Node * > &nodes)
Creates a deep copy of a Node vector.
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition: Element.cpp:225
std::vector< Element * > copyElementVector(std::vector< Element * > const &elements, std::vector< Node * > const &new_nodes, std::vector< std::size_t > const *const node_id_map)
bool includesNodeID(std::vector< MeshLib::Node * > const &vec_nodes, std::size_t node_id)
Definition: PostUtils.cpp:22
std::vector< int > const & getMaterialIdsForNode(std::vector< std::pair< std::size_t, std::vector< int >>> const &vec_nodeID_matIDs, std::size_t nodeID)
Definition: PostUtils.cpp:30

References _map_dup_newNodeIDs, _org_mesh, _output_mesh, calculateTotalDisplacement(), MeshLib::copyElementVector(), MeshLib::copyNodeVector(), copyPropertyValues(), createProperty(), BaseLib::findFirstNotEqualElement(), BaseLib::findIndex(), MeshLib::Mesh::getDimension(), MeshLib::Mesh::getElements(), ProcessLib::LIE::anonymous_namespace{PostUtils.cpp}::getMaterialIdsForNode(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNode(), MeshLib::getNodeIndex(), MeshLib::Mesh::getNodes(), MeshLib::Element::getNumberOfNodes(), MeshLib::Mesh::getProperties(), MeshLib::Properties::getPropertyVector(), MeshLib::Properties::hasPropertyVector(), ProcessLib::LIE::anonymous_namespace{PostUtils.cpp}::includesNodeID(), MaterialPropertyLib::name, OGS_FATAL, and MeshLib::Element::setNode().

Member Function Documentation

◆ calculateTotalDisplacement()

void ProcessLib::LIE::PostProcessTool::calculateTotalDisplacement ( unsigned const  n_fractures,
unsigned const  n_junctions 
)
private

Definition at line 376 of file PostUtils.cpp.

378 {
379  auto const& u = *_output_mesh->getProperties().getPropertyVector<double>(
380  "displacement");
381  auto const n_u_comp = u.getNumberOfGlobalComponents();
382  assert(u.size() == _output_mesh->getNodes().size() * 3);
383  auto& total_u =
384  *_output_mesh->getProperties().createNewPropertyVector<double>(
385  "u", MeshLib::MeshItemType::Node, n_u_comp);
386  total_u.resize(u.size());
387  std::copy(cbegin(u), cend(u), begin(total_u));
388 
389  for (unsigned enrich_id = 0; enrich_id < n_fractures + n_junctions;
390  enrich_id++)
391  {
392  // nodal value of levelset
393  std::vector<double> nodal_levelset(
394  _output_mesh->getNodes().size(),
395  std::numeric_limits<double>::quiet_NaN());
396 
397  auto const& ele_levelset =
398  *_output_mesh->getProperties().getPropertyVector<double>(
399  "levelset" + std::to_string(enrich_id + 1));
400  for (MeshLib::Element const* e : _output_mesh->getElements())
401  {
402  if (e->getDimension() != _output_mesh->getDimension())
403  {
404  continue;
405  }
406  const double e_levelset = ele_levelset[e->getID()];
407 
408  for (unsigned i = 0; i < e->getNumberOfNodes(); i++)
409  {
410  nodal_levelset[getNodeIndex(*e, i)] = e_levelset;
411  }
412  }
413 
414  // update total displacements
415  auto const& g =
416  *_output_mesh->getProperties().getPropertyVector<double>(
417  "displacement_jump" + std::to_string(enrich_id + 1));
418  for (unsigned i = 0; i < _output_mesh->getNodes().size(); i++)
419  {
420  for (int j = 0; j < n_u_comp; j++)
421  {
422  total_u[i * n_u_comp + j] +=
423  nodal_levelset[i] * g[i * n_u_comp + j];
424  }
425  }
426  }
427 }
void copy(PETScVector const &x, PETScVector &y)
Definition: LinAlg.cpp:37

References _output_mesh, MathLib::LinAlg::copy(), MeshLib::getNodeIndex(), and MeshLib::Node.

Referenced by PostProcessTool().

◆ copyPropertyValues()

template<typename T >
void ProcessLib::LIE::PostProcessTool::copyPropertyValues ( MeshLib::PropertyVector< T > const &  source_property,
MeshLib::PropertyVector< T > *const  destination_property 
)
private

Definition at line 323 of file PostUtils.cpp.

326 {
327  if (destination_property == nullptr)
328  {
329  // skip the copy, because the destination wasn't created.
330  return;
331  }
332 
333  auto const item_type = source_property.getMeshItemType();
334  if (item_type == MeshLib::MeshItemType::Node)
335  {
336  auto const n_src_comp = source_property.getNumberOfGlobalComponents();
337  auto const n_dest_comp =
338  destination_property->getNumberOfGlobalComponents();
339  // copy existing
340  for (unsigned i = 0; i < _org_mesh.getNumberOfNodes(); i++)
341  {
342  auto last = std::copy_n(&source_property[i * n_src_comp],
343  n_src_comp,
344  &(*destination_property)[i * n_dest_comp]);
345  // set zero for components not existing in the original
346  std::fill_n(last, n_dest_comp - n_src_comp, T{0});
347  }
348  // copy duplicated
349  for (auto itr : _map_dup_newNodeIDs)
350  {
351  for (unsigned k = 0; k < itr.second.size(); k++)
352  {
353  std::copy_n(
354  &(*destination_property)[itr.first * n_dest_comp],
355  n_dest_comp,
356  &(*destination_property)[itr.second[k] * n_dest_comp]);
357  }
358  }
359  }
360  else if (item_type == MeshLib::MeshItemType::Cell)
361  {
362  assert(source_property.size() == destination_property->size());
363  std::copy(source_property.begin(), source_property.end(),
364  destination_property->begin());
365  }
366  else
367  {
368  OGS_FATAL(
369  "Property '{:s}' values cannot be copied because its mesh item "
370  "type '{:s}' is not supported. Unexpected error, because the "
371  "destination property was created.",
372  source_property.getPropertyName(), toString(item_type));
373  }
374 }
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition: Mesh.h:89
std::string const & getPropertyName() const
MeshItemType getMeshItemType() const
int getNumberOfGlobalComponents() const
std::size_t size() const
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)
Converts MGIS kinematic to a string representation.
Definition: MFront.cpp:103

References _map_dup_newNodeIDs, _org_mesh, MeshLib::Cell, MathLib::LinAlg::copy(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::Mesh::getNumberOfNodes(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::Node, OGS_FATAL, MeshLib::PropertyVector< PROP_VAL_TYPE >::size(), and MaterialLib::Solids::MFront::toString().

Referenced by PostProcessTool().

◆ createProperty()

template<typename T >
MeshLib::PropertyVector< T > * ProcessLib::LIE::PostProcessTool::createProperty ( MeshLib::PropertyVector< T > const &  property)
private

Definition at line 287 of file PostUtils.cpp.

289 {
290  auto const item_type = property.getMeshItemType();
291  auto const n_src_comp = property.getNumberOfGlobalComponents();
292  // convert 2D vector to 3D. Otherwise Paraview Calculator filter does
293  // not recognize it as a vector
294  auto const n_dest_comp = (n_src_comp == 2) ? 3 : n_src_comp;
295 
296  auto new_property = MeshLib::getOrCreateMeshProperty<T>(
297  *_output_mesh, property.getPropertyName(), item_type, n_dest_comp);
298 
299  if (item_type == MeshLib::MeshItemType::Node)
300  {
301  assert(new_property->size() ==
302  _output_mesh->getNumberOfNodes() * n_dest_comp);
303  }
304  else if (item_type == MeshLib::MeshItemType::Cell)
305  {
306  assert(new_property->size() ==
307  _output_mesh->getNumberOfElements() * n_dest_comp);
308  }
309  else
310  {
311  WARN(
312  "Property '{:s}' cannot be created because its mesh item type "
313  "'{:s}' is not supported.",
314  property.getPropertyName(), toString(item_type));
315  _output_mesh->getProperties().removePropertyVector(
316  new_property->getPropertyName());
317  return nullptr;
318  }
319  return new_property;
320 }
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:37

References _output_mesh, MeshLib::Cell, MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::Node, MaterialLib::Solids::MFront::toString(), and WARN().

Referenced by PostProcessTool().

◆ getOutputMesh()

MeshLib::Mesh const& ProcessLib::LIE::PostProcessTool::getOutputMesh ( ) const
inline

Definition at line 44 of file PostUtils.h.

44 { return *_output_mesh; }

References _output_mesh.

Referenced by anonymous_namespace{postLIE.cpp}::postVTU().

Member Data Documentation

◆ _map_dup_newNodeIDs

std::map<std::size_t, std::vector<std::size_t> > ProcessLib::LIE::PostProcessTool::_map_dup_newNodeIDs
private

Definition at line 59 of file PostUtils.h.

Referenced by PostProcessTool(), and copyPropertyValues().

◆ _org_mesh

MeshLib::Mesh const& ProcessLib::LIE::PostProcessTool::_org_mesh
private

Definition at line 57 of file PostUtils.h.

Referenced by PostProcessTool(), and copyPropertyValues().

◆ _output_mesh

std::unique_ptr<MeshLib::Mesh> ProcessLib::LIE::PostProcessTool::_output_mesh
private

The documentation for this class was generated from the following files: