SelectionByMapping.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23  \ *---------------------------------------------------------------------------*/
24 
25 #include "MeshSelection.hpp"
26 #include "MimmoGeometry.hpp"
27 #include "SkdTreeUtils.hpp"
28 
29 namespace mimmo{
30 
37  m_name = "mimmo.SelectionByMapping";
39  m_tolerance = 1.E-08;
40 
41  topo = std::max(1,topo);
42  if(topo > 4 || topo == 3) topo=1;
43  m_topo = topo;
44 
45  m_allowedType.resize(5);
46  m_allowedType[1].insert(FileType::STL);
47  m_allowedType[1].insert(FileType::SURFVTU);
48  m_allowedType[1].insert(FileType::NAS);
49  m_allowedType[1].insert(FileType::MIMMO);
50  m_allowedType[1].insert(FileType::CURVEVTU);
51 
52  m_allowedType[2].insert(FileType::VOLVTU);
53  m_allowedType[2].insert(FileType::MIMMO);
54 
55  m_allowedType[4].insert(FileType::CURVEVTU);
56  m_allowedType[4].insert(FileType::MIMMO);
57 
58  m_allowedTopology.resize(5);
59  m_allowedTopology[1].insert(1);
60  m_allowedTopology[1].insert(4);
61 
62  m_allowedTopology[2].insert(2);
63 
64  m_allowedTopology[4].insert(4);
65 
66 };
67 
72 SelectionByMapping::SelectionByMapping(const bitpit::Config::Section & rootXML){
73 
74  m_name = "mimmo.SelectionByMapping";
76  m_tolerance = 1.E-08;
77 
78  std::string fallback_name = "ClassNONE";
79  std::string fallback_topo = "-1";
80  std::string input_name = rootXML.get("ClassName", fallback_name);
81  input_name = bitpit::utils::string::trim(input_name);
82 
83  std::string input_topo = rootXML.get("Topology", fallback_topo);
84  input_topo = bitpit::utils::string::trim(input_topo);
85 
86  int topo = std::stoi(input_topo);
87  topo = std::max(1,topo);
88  if(topo > 4 || topo == 3) topo=1;
89  m_topo = topo;
90 
91  m_allowedType.resize(5);
92  m_allowedType[1].insert(FileType::STL);
93  m_allowedType[1].insert(FileType::SURFVTU);
94  m_allowedType[1].insert(FileType::NAS);
95  m_allowedType[1].insert(FileType::MIMMO);
96  m_allowedType[1].insert(FileType::CURVEVTU);
97 
98  m_allowedType[2].insert(FileType::VOLVTU);
99  m_allowedType[2].insert(FileType::MIMMO);
100 
101  m_allowedType[4].insert(FileType::CURVEVTU);
102  m_allowedType[4].insert(FileType::MIMMO);
103 
104  m_allowedTopology.resize(5);
105  m_allowedTopology[1].insert(1);
106  m_allowedTopology[1].insert(4);
107 
108  m_allowedTopology[2].insert(2);
109 
110  m_allowedTopology[4].insert(4);
111 
112  if(input_name == "mimmo.SelectionByMapping"){
113  absorbSectionXML(rootXML);
114  }else{
116  };
117 }
118 
126 SelectionByMapping::SelectionByMapping(std::unordered_map<std::string, int> & geolist, mimmo::MimmoSharedPointer<MimmoObject> target, double tolerance){
127  m_name = "mimmo.SelectionByMapping";
129  m_tolerance = 1.E-08;
130 
131  m_allowedType.resize(5);
132  m_allowedType[1].insert(FileType::STL);
133  m_allowedType[1].insert(FileType::SURFVTU);
134  m_allowedType[1].insert(FileType::NAS);
135  m_allowedType[1].insert(FileType::MIMMO);
136  m_allowedType[1].insert(FileType::CURVEVTU);
137 
138  m_allowedType[2].insert(FileType::VOLVTU);
139  m_allowedType[2].insert(FileType::MIMMO);
140 
141  m_allowedType[4].insert(FileType::CURVEVTU);
142  m_allowedType[4].insert(FileType::MIMMO);
143 
144  m_allowedTopology.resize(5);
145  m_allowedTopology[1].insert(1);
146  m_allowedTopology[1].insert(4);
147 
148  m_allowedTopology[2].insert(2);
149 
150  m_allowedTopology[4].insert(4);
151 
152  if(target == nullptr) return;
153 
154  m_topo = target->getType();
155  m_topo = std::min(1, m_topo);
156  if(m_topo > 4 || m_topo == 3) m_topo = 1;
157  setGeometry(target);
158  setFiles(geolist);
159  m_tolerance = tolerance;
160 
161 };
162 
167 
172  m_tolerance = other.m_tolerance;
173  m_geolist = other.m_geolist;
174  m_mimmolist = other.m_mimmolist;
175  m_allowedType = other.m_allowedType;
176  m_allowedTopology = other.m_allowedTopology;
177 };
178 
183  swap(other);
184  return *this;
185 };
186 
193 {
194  std::swap(m_tolerance, x.m_tolerance);
195  std::swap(m_geolist, x.m_geolist);
196  std::swap(m_mimmolist, x.m_mimmolist);
197  std::swap(m_allowedType, x.m_allowedType);
198  std::swap(m_allowedTopology, x.m_allowedTopology);
199 
201 }
202 
203 
207 void
209 
211  bool built = m_arePortsBuilt;
212 
213  built = (built && createPortIn<mimmo::MimmoSharedPointer<MimmoObject>, SelectionByMapping>(this, &SelectionByMapping::addMappingGeometry,M_GEOM2));
214 
215  m_arePortsBuilt = built;
216 };
217 
222 double
224  return m_tolerance;
225 };
226 
232 void
234  if(tol < 0.0){
235  tol = 1.e-8;
236  }
237  m_tolerance = tol;
238 };
239 
245 void
247 
248  if(target == nullptr){
249  (*m_log)<< m_name << " attempt to link null target geometry. Do nothing." << std::endl;
250  return;
251  }
252 
253  if(target->getType() != m_topo){
254  (*m_log)<< " " << std::endl;
255  (*m_log)<< m_name << " target Topology : "<< target->getType() << std::endl;
256  (*m_log)<<" supported Topology : "<< m_topo << std::endl;
257  (*m_log)<< m_name << " cannot support current geometry. Topology not supported."<<std::endl;
258  (*m_log)<< " " << std::endl;
259  return;
260  }
261 
262  m_geometry = target;
263 
264 };
265 
270 const std::unordered_map<std::string, int> &
272  return m_geolist;
273 }
274 
279 void
280 SelectionByMapping::setFiles(std::unordered_map<std::string, int> files){
281  for(auto && val : files){
282  addFile(val);
283  }
284 };
285 
290 void
291 SelectionByMapping::addFile(std::pair<std::string, int> file){
292  int type = m_topo;
293  if(m_allowedType[type].find(file.second) != m_allowedType[type].end()){
294  m_geolist.insert(file);
295  }
296 };
297 
302 void
304  if(m_allowedTopology[m_topo].count(obj->getType()) > 0){
305  m_mimmolist.insert(obj);
306  }
307 };
308 
313 void
315  if(m_geolist.find(file) != m_geolist.end()) m_geolist.erase(file);
316 };
317 
321 void
323  m_geolist.clear();
324 };
325 
329 void
331  m_mimmolist.clear();
332 };
333 
337 void
339  m_subpatch.reset();
340  removeFiles();
343 };
344 
351 
352  // Build skd tree (check on sync status is done inside the method)
353  getGeometry()->buildSkdTree();
354 
355  std::set<long> cellList;
356  for (auto & file : m_geolist){
357  livector1D list = getProximity(file);
358  cellList.insert(list.begin(), list.end());
359  }
360 
361  for (auto & mimmoptr : m_mimmolist){
362  livector1D list = getProximity(mimmoptr);
363  cellList.insert(list.begin(), list.end());
364  }
365 
366 /* check if dual */
367  livector1D result;
368  if(m_dual){
369  livector1D totID = getGeometry()->getCellsIds();
370  result.resize(totID.size() - cellList.size());
371  if(result.size() == 0) return result;
372 
373  std::sort(totID.begin(), totID.end());
374  int counter = 0;
375  auto tot_it = totID.begin();
376  auto cand_it = cellList.begin();
377  while(tot_it != totID.end()){
378  long val = *tot_it;
379  if (cand_it == cellList.end() || val != *cand_it) {
380  result[counter] = val;
381  ++counter;
382  } else {
383  ++cand_it;
384  }
385  ++tot_it;
386  }
387  }else{
388  result.insert(result.end(), cellList.begin(), cellList.end());
389  }
390  return result;
391 };
392 
399 SelectionByMapping::getProximity(std::pair<std::string, int> val){
400 
401  svector1D info = extractInfo(val.first);
402 
404  geo->setDir(info[0]);
405  geo->setFilename(info[1]);
406  geo->setFileType(val.second);
407  geo->setBuildSkdTree(true);
408  geo->execute();
409 
410  if(geo->getGeometry()->getType() == 3 ){
411  m_log->setPriority(bitpit::log::NORMAL);
412  (*m_log)<< m_name << " failed to read or unsuitable geometry in SelectionByMapping::getProximity"<<std::endl;
413  m_log->setPriority(bitpit::log::DEBUG);
414  return livector1D();
415  }
416 
417 #if MIMMO_ENABLE_MPI
418  livector1D result = mimmo::skdTreeUtils::selectByGlobalPatch(geo->getGeometry()->getSkdTree(), getGeometry()->getSkdTree(), m_tolerance);
419 #else
420  livector1D result = mimmo::skdTreeUtils::selectByPatch(geo->getGeometry()->getSkdTree(), getGeometry()->getSkdTree(), m_tolerance);
421 #endif
422 
423  delete geo;
424  geo = nullptr;
425 
426  return result;
427 };
428 
434 SelectionByMapping::getProximity(mimmo::MimmoSharedPointer<MimmoObject> obj){
435 
436  // Build skd tree (check on sync status is done inside the method)
437  obj->buildSkdTree();
438 
439 #if MIMMO_ENABLE_MPI
440  livector1D result = mimmo::skdTreeUtils::selectByGlobalPatch(obj->getSkdTree(), getGeometry()->getSkdTree(), m_tolerance);
441 #else
442  livector1D result = mimmo::skdTreeUtils::selectByPatch(obj->getSkdTree(), getGeometry()->getSkdTree(), m_tolerance);
443 #endif
444 
445  return result;
446 };
447 
452 svector1D
453 SelectionByMapping::extractInfo(std::string file){
454 
455  std::string root, name, tag,temp;
456  std::string key1=".", key2="/\\";
457 
458  std::size_t found = file.find_last_of(key2);
459  root = file.substr(0, found);
460  temp = file.substr(found+1);
461 
462  found = temp.find_last_of(key1);
463  name = temp.substr(0,found);
464  tag = temp.substr(found+1);
465 
466  svector1D result(3);
467  result[0] = root;
468  result[1] = name;
469  result[2] = tag;
470 
471  return result;
472 }
473 
479 void
480 SelectionByMapping::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
481 
482  BITPIT_UNUSED(name);
483 
484  //checking topology
485  if(slotXML.hasOption("Topology")){
486  std::string input = slotXML.get("Topology");
487  input = bitpit::utils::string::trim(input);
488  int temp = -1;
489  if(!input.empty()){
490  std::stringstream ss(input);
491  ss>>temp;
492  }
493  if(m_topo != temp) {
494  throw std::runtime_error (m_name + " : xml absorbing failed.");
495  }
496  }
497 
498  BaseManipulation::absorbSectionXML(slotXML, name);
499  //start absorbing
500  if(slotXML.hasOption("Dual")){
501  std::string input = slotXML.get("Dual");
502  input = bitpit::utils::string::trim(input);
503  bool value = false;
504  if(!input.empty()){
505  std::stringstream ss(input);
506  ss >> value;
507  }
508  setDual(value);
509  }
510 
511  if(slotXML.hasOption("Tolerance")){
512  std::string input = slotXML.get("Tolerance");
513  input = bitpit::utils::string::trim(input);
514  double temp = 1.0E-8;
515  if(!input.empty()){
516  std::stringstream ss(input);
517  ss>>temp;
518  }
519  setTolerance(temp);
520 
521  }
522 
523  std::unordered_map<std::string, int> mapp;
524  if(slotXML.hasSection("Files")){
525 
526  const bitpit::Config::Section & filesXML = slotXML.getSection("Files");
527 
528  for(auto & subfile : filesXML.getSections()){
529  std::string path;
530  std::string tag;
531 
532  if(subfile.second->hasOption("fullpath")) {
533  path = subfile.second->get("fullpath");
534  path = bitpit::utils::string::trim(path);
535  }
536  if(subfile.second->hasOption("tag")){
537  tag = subfile.second->get("tag");
538  tag = bitpit::utils::string::trim(tag);
539  //check tag;
540  auto maybe_tag = FileType::_from_string_nothrow(tag.c_str());
541  if(!maybe_tag) tag.clear();
542  else tag = maybe_tag->_to_string();
543  }
544 
545  if(!path.empty() && !tag.empty()){
546  mapp[path] = (int) FileType::_from_string(tag.c_str());
547  }
548  }
549 
550  setFiles(mapp);
551 
552  }
553 
554 };
555 
561 void SelectionByMapping::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
562 
563  BITPIT_UNUSED(name);
564 
565  BaseManipulation::flushSectionXML(slotXML, name);
566 
567  slotXML.set("Topology", m_topo);
568 
569  int value = m_dual;
570  slotXML.set("Dual", std::to_string(value));
571 
572 
573  if(m_tolerance != 1.E-08){
574  std::stringstream ss;
575  ss<<std::scientific<<m_tolerance;
576  slotXML.set("Tolerance", ss.str());
577  }
578 
579  bitpit::Config::Section & filesXML = slotXML.addSection("Files");
580 
581  int counter = 0;
582  for(auto & file : m_geolist){
583  std::string name = "file"+std::to_string(counter);
584  bitpit::Config::Section & local = filesXML.addSection(name);
585  local.set("fullpath", file.first);
586  std::string typetag = (FileType::_from_integral(file.second))._to_string();
587  local.set("tag", typetag);
588  ++counter;
589  }
590 
591 };
592 
593 }
Abstract Interface for selection classes.
void setTolerance(double tol=1.e-8)
void setGeometry(mimmo::MimmoSharedPointer< MimmoObject > geometry)
void addFile(std::pair< std::string, int >)
std::vector< std::string > svector1D
void swap(SelectionByMapping &) noexcept
const std::unordered_map< std::string, int > & getFiles() const
void setBuildSkdTree(bool build)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
std::vector< long > livector1D
#define M_GEOM2
mimmo::MimmoSharedPointer< MimmoObject > m_subpatch
void warningXML(bitpit::Logger *log, std::string name)
void setFileType(FileType type)
Selection mapping external surfaces/volume/3D curves on a target mesh of the same topology.
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
SelectionByMapping & operator=(SelectionByMapping other)
void setFiles(std::unordered_map< std::string, int >)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
MimmoGeometry is an executable block class wrapping(linking or internally instantiating) a Mimmo Obje...
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
MimmoSharedPointer< MimmoObject > m_geometry
void addMappingGeometry(mimmo::MimmoSharedPointer< MimmoObject > obj)
std::vector< long > selectByPatch(bitpit::PatchSkdTree *selection, bitpit::PatchSkdTree *target, double tol)
void swap(GenericSelection &x) noexcept
void setFilename(std::string filename)
void setDual(bool flag=false)
MimmoSharedPointer is a custom implementation of shared pointer.
MimmoSharedPointer< MimmoObject > getGeometry()
void setDir(std::string dir)