BaseManipulation.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 #include "BaseManipulation.hpp"
25 #include <utility>
26 #include <map>
27 
28 namespace mimmo {
29 
31 
37  m_geometry = nullptr;
38  m_portsType = ConnectionType::BOTH;
39  m_name = "mimmo";
40  m_active = true;
41  m_arePortsBuilt = false;
42  m_execPlot = false;
43  m_outputPlot = "./";
45  m_priority = 0;
46  m_apply = false;
48 
49 #if MIMMO_ENABLE_MPI
50  int initialized;
51  MPI_Initialized(&initialized);
52  if (!initialized)
53  MPI_Init(nullptr, nullptr);
54 
55  //Fixed MPI comm world
56  MPI_Comm_dup(MPI_COMM_WORLD, &m_communicator);
57 
58  MPI_Comm_rank(MPI_COMM_WORLD, &m_rank);
59  MPI_Comm_size(MPI_COMM_WORLD, &m_nprocs);
60 
61 #endif
62 
63  bool logexists = bitpit::log::manager().exists(MIMMO_LOG_FILE);
64  if (m_counter == 1)
65  initializeLogger(logexists);
66  else
67  m_log = &bitpit::log::cout(MIMMO_LOG_FILE);
68 
69 };
70 
75  clear();
76  deletePorts();
77 };
78 
84  m_geometry = other.m_geometry;
85  m_portsType = other.m_portsType;
86  m_name = other.m_name;
87  m_active = other.m_active;
88  m_arePortsBuilt = false;
89  m_execPlot = other.m_execPlot;
90  m_outputPlot = other.m_outputPlot;
91 
92  //only for copy construction
95 
96  m_priority = other.m_priority;
97  m_apply = other.m_apply;
98 
99  //logger is ready, since another BaseManipulation other, is instantiated.
100  m_log = &bitpit::log::cout(MIMMO_LOG_FILE);
101 
102 #if MIMMO_ENABLE_MPI
103  m_rank = other.m_rank;
104  m_nprocs = other.m_nprocs;
105  MPI_Comm_dup(other.m_communicator, &m_communicator);
106 #endif
107 };
108 
114 
115  //NOT CAS type, since the class is abstract.
116  //Please note static members or link to static members are not copied.
117  //Port connection and port building members are not copied.
118  m_geometry = other.m_geometry;
119  m_portsType = other.m_portsType;
120  m_name = other.m_name;
121  m_active = other.m_active;
122  m_execPlot = other.m_execPlot;
123  m_outputPlot = other.m_outputPlot;
124  m_priority = other.m_priority;
125  m_apply = other.m_apply;
126 #if MIMMO_ENABLE_MPI
127  MPI_Comm_dup(other.m_communicator, &m_communicator);
128  m_rank = other.m_rank;
129  m_nprocs = other.m_nprocs;
130 #endif
131  return *this;
132 };
133 
141 {
142  std::swap(m_priority, x.m_priority);
143  std::swap(m_name, x.m_name);
144  m_geometry.swap(x.m_geometry);
145  std::swap(m_portsType, x.m_portsType);
146  std::swap(m_active, x.m_active);
147  std::swap(m_execPlot, x.m_execPlot);
148  std::swap(m_apply, x.m_apply);
149  std::swap(m_outputPlot, x.m_outputPlot);
150 #if MIMMO_ENABLE_MPI
151  std::swap(m_communicator, x.m_communicator);
152  std::swap(m_rank, x.m_rank);
153  std::swap(m_nprocs, x.m_nprocs);
154 #endif
155 
156 }
157 
163 void
165  if (!logexist){
166 #if MIMMO_ENABLE_MPI
167  bitpit::log::manager().initialize(bitpit::log::Mode::COMBINED, MIMMO_LOG_FILE, true, MIMMO_LOG_DIR, m_nprocs, m_rank);
168 #else
169  bitpit::log::manager().initialize(bitpit::log::Mode::COMBINED, MIMMO_LOG_FILE, true, MIMMO_LOG_DIR);
170 #endif
171  }
172  m_log = &bitpit::log::cout(MIMMO_LOG_FILE);
173  bitpit::log::setVisibility((*m_log), bitpit::log::Visibility::MASTER);
174  bitpit::log::setConsoleVerbosity((*m_log), bitpit::log::NORMAL);
175  bitpit::log::setFileVerbosity((*m_log), bitpit::log::NORMAL);
176  if (m_counter == 1){
177 #if MIMMO_ENABLE_MPI
178  if (m_rank == 0){
179 #endif
180  (*m_log) << bitpit::log::priority(bitpit::log::NORMAL);
181  (*m_log) << bitpit::log::context("mimmo");
182  (*m_log) << "--------------------------------------------------" << std::endl;
183  (*m_log) << "- mimmo - Surface manipulation and mesh morphing -" << std::endl;
184  (*m_log) << "--------------------------------------------------" << std::endl;
185  (*m_log) << " " << std::endl;
186  (*m_log) << bitpit::log::priority(bitpit::log::DEBUG);
187 #if MIMMO_ENABLE_MPI
188  }
189 #endif
190  }
191 }
192 
196 bitpit::Logger&
198  return (*m_log);
199 }
200 
205 bool
207  return(m_arePortsBuilt);
208 }
209 
215 uint
217  return m_priority;
218 }
219 
224 std::string
226  return m_name;
227 };
228 
236  return m_geometry;
237 };
238 
246  return m_geometry;
247 };
248 
253 int
255  return m_parent.size();
256 };
257 
265  if (i>(int)m_parent.size()-1) return nullptr;
266  return next(m_parent.begin(), i)->first;
267 };
268 
275 bool
277  std::unordered_map<BaseManipulation *, int>::iterator it;
278  it = m_parent.find(target);
279  index = -1;
280  if(it == m_parent.end()) return false;
281 
282  index = distance(m_parent.begin(), it);
283  return true;
284 };
285 
290 int
292  return m_child.size();
293 };
294 
302  if (i>(int)m_child.size()-1) return nullptr;
303  return next(m_child.begin(), i)->first;
304 };
305 
312 bool
314  std::unordered_map<BaseManipulation *, int>::iterator it;
315  it = m_child.find(target);
316  index = -1;
317  if(it == m_child.end()) return false;
318 
319  index = distance(m_child.begin(), it);
320  return true;
321 };
322 
329  return (m_portsType);
330 }
331 
336 int
338  return (m_portIn.size());
339 }
340 
345 int
347  return (m_portOut.size());
348 }
349 
354 std::unordered_map<PortID, PortIn*>
356  return (m_portIn);
357 }
358 
363 std::unordered_map<PortID, PortOut*>
365  return (m_portOut);
366 }
367 
371 bool
373  return (m_execPlot);
374 }
375 
379 bool
381  return (m_apply);
382 }
383 
388 bool
390  return (m_active);
391 }
392 
393 
397 int
399  return m_counter;
400 }
401 
405 void
406 BaseManipulation::setLog(bitpit::Logger& log){
407  m_log = &log;
408 }
409 
415 void
417  m_priority = priority;
418 };
419 
424 void
425 BaseManipulation::setName(std::string name){
426  m_name = name;
427 };
428 
432 void
434  m_geometry = geometry;
435 };
436 
442 void
444  m_execPlot = flag;
445 }
446 
452 void
454  if(path.empty()) path = ".";
455  m_outputPlot = path;
456 }
457 
462 void
464  m_apply = flag;
465 }
466 
471 void
473  m_counter = id;
474 }
475 
479 void
481  m_active = true;
482 };
483 
487 void
489  m_active = false;
490 };
491 
495 void
497  m_geometry = nullptr;
498 };
499 
504 void
506  removePinsIn();
507  removePinsOut();
508 }
509 
514 void
516  std::unordered_map<BaseManipulation*, int>::iterator it;
517  while(m_parent.size()){
518  it = m_parent.begin();
519  mimmo::pin::removeAllPins(it->first, this);
520  }
521 }
522 
527 void
529  std::unordered_map<BaseManipulation*, int>::iterator it;
530  while(m_child.size()){
531  it = m_child.begin();
532  mimmo::pin::removeAllPins(this, it->first);
533  }
534 }
535 
539 void
541  unsetGeometry();
542  removePins();
543  m_execPlot = false;
544  m_outputPlot = ".";
545 };
546 
551 void
553 
554  if (!MIMMO_EXPERT){
555  std::map<int, std::vector<PortIn*> > families;
556  std::map<int, std::vector<PortID> > familiesID;
557  for (std::unordered_map<PortID, PortIn*>::iterator i=m_portIn.begin(); i!=m_portIn.end(); i++){
558  if (i->second->isMandatory()){
559  families[i->second->getFamily()].push_back(i->second);
560  familiesID[i->second->getFamily()].push_back(i->first);
561  }
562  }
563  std::map<int, std::vector<PortID> >::iterator itID = familiesID.begin();
564  for (std::map<int, std::vector<PortIn*> >::iterator i=families.begin(); i!=families.end(); i++){
565  if (i->first == 0){
566  int count = 0;
567  for (auto ip : i->second){
568  std::vector<BaseManipulation*> linked = ip->getLink();
569  if (linked.size() == 0){
570  (*m_log) << "error: " << m_name << " mandatory port " << itID->second[count] << " not linked -> exit! " << std::endl;
571  throw std::runtime_error (m_name + " mandatory port " + itID->second[count] + " not linked");
572  }
573  count++;
574  }
575  }
576  else{
577  bool check = false;
578  for (auto ip : i->second){
579  std::vector<BaseManipulation*> linked = ip->getLink();
580  check = check || linked.size();
581  }
582  if (!check){
583  (*m_log) << "error: " << m_name << " none of mandatory ports " << itID->second << " linked -> exit! " << std::endl;
584  std::string ports;
585  for (auto p : itID->second)
586  ports += " " + p + " ";
587  throw std::runtime_error (m_name + " none of mandatory ports " + ports + " linked");
588  }
589  }
590  itID++;
591  }
592  }
593 
594  if (m_active) execute();
595 
596  for (std::unordered_map<PortID, PortOut*>::iterator i=m_portOut.begin(); i!=m_portOut.end(); i++){
597  std::vector<BaseManipulation*> linked = i->second->getLink();
598  if (linked.size() > 0){
599  i->second->exec();
600  }
601  }
602 
604  if(isApply()) apply();
605 }
606 
614 void
615 BaseManipulation::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
616  BITPIT_UNUSED(name);
617 
618  std::string input;
619  if(slotXML.hasOption("Priority")){
620  input = slotXML.get("Priority");
621  int value =0;
622  if(!input.empty()){
623  std::stringstream ss(bitpit::utils::string::trim(input));
624  ss>>value;
625  }
626  setPriority(value);
627  };
628 
629 
630  if(slotXML.hasOption("Apply")){
631  std::string input = slotXML.get("Apply");
632  input = bitpit::utils::string::trim(input);
633  bool value = false;
634  if(!input.empty()){
635  std::stringstream ss(input);
636  ss >> value;
637  }
638  setApply(value);
639  }
640 
641  if(slotXML.hasOption("PlotInExecution")){
642  std::string input = slotXML.get("PlotInExecution");
643  input = bitpit::utils::string::trim(input);
644  bool value = false;
645  if(!input.empty()){
646  std::stringstream ss(input);
647  ss >> value;
648  }
649  setPlotInExecution(value);
650  }
651 
652  if(slotXML.hasOption("OutputPlot")){
653  std::string input = slotXML.get("OutputPlot");
654  input = bitpit::utils::string::trim(input);
655  std::string temp = ".";
656  if(!input.empty()) setOutputPlot(input);
657  else setOutputPlot(temp);
658  }
659 
660 }
661 
669 void
670 BaseManipulation::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
671 
672  BITPIT_UNUSED(name);
673 
674  slotXML.set("ClassName", m_name);
675  slotXML.set("Priority", std::to_string(getPriority()));
676 
677  if(isApply()){
678  slotXML.set("Apply", std::to_string(1));
679  }
680  if(isPlotInExecution()){
681  slotXML.set("PlotInExecution", std::to_string(1));
682  slotXML.set("OutputPlot", m_outputPlot);
683  }
684 }
685 
689 void
691  for (std::unordered_map<PortID, PortOut*>::iterator i = m_portOut.begin(); i != m_portOut.end(); i++){
692  delete i->second;
693  i->second = nullptr;
694  }
695  for (std::unordered_map<PortID, PortIn*>::iterator i = m_portIn.begin(); i != m_portIn.end(); i++){
696  delete i->second;
697  i->second = nullptr;
698  }
699 }
700 
706 void
708  m_portIn[port]->m_ibuffer = input;
709 }
710 
716 void
718  m_portIn[port]->readBuffer();
719 }
720 
725 void
727  m_portIn[port]->cleanBuffer();
728 }
729 
734 void
736 
737  if(!m_parent.count(parent)){
738  m_parent.insert(std::pair<BaseManipulation*,int>(parent,1)); //add new parent with counter 1;
739  }else{
740  m_parent[parent]++; //just incrementing pre-existent parent counter;
741  }
742 };
743 
748 void
750  if(!m_child.count(child)){
751  m_child.insert(std::pair<BaseManipulation*,int>(child,1)); //add new child with counter 1;
752  }else{
753  m_child[child]++; //just incrementing pre-existent child counter;
754  }
755 };
756 
763 void
765 
766  std::unordered_map<BaseManipulation*, int>::iterator got = m_parent.find(parent);
767  if(got != m_parent.end()){
768  m_parent[parent]--;
769  if(m_parent[parent] <1) m_parent.erase(parent);
770  }
771 };
772 
779 void
781  std::unordered_map<BaseManipulation*, int>::iterator got = m_child.find(child);
782  if(got != m_child.end()){
783  m_child[child]--;
784  if(m_child[child] <1) m_child.erase(child);
785  }
786 };
787 
794 PortID
796  for (std::unordered_map<PortID, PortIn*>::iterator i=m_portIn.begin(); i!=m_portIn.end(); i++){
797  if (pin == *(i->second)) return(i->first);
798  }
799  return("NONE");
800 }
801 
808 PortID
810  for (std::unordered_map<PortID, PortOut*>::iterator i=m_portOut.begin(); i!=m_portOut.end(); i++){
811  if (pin == *(i->second)) return(i->first);
812  }
813  return("NONE");
814 }
815 
820 void
822  if (objIn != nullptr && m_portIn.count(portR) !=0 ){
823  m_portIn[portR]->m_objLink.push_back(objIn);
824  }
825 };
826 
832 void
834  if (objOut != nullptr && m_portOut.count(portS) != 0 ){
835  if (objOut->m_portIn.count(portR) != 0){
836  m_portOut[portS]->m_objLink.push_back(objOut);
837  m_portOut[portS]->m_portLink.push_back(portR);
838  }
839  }
840 };
841 
846 void
848  if (objIn != nullptr && m_portIn.count(portR) != 0){
849  std::vector<BaseManipulation*> linked = m_portIn[portR]->getLink();
850  for (int i=0; i<(int)linked.size(); i++){
851  if (linked[i] == objIn){
852  m_portIn[portR]->clear(i);
853  }
854  }
855  }
856 };
857 
862 void
864  if (objOut != nullptr && m_portOut.count(portS) != 0){
865  std::vector<BaseManipulation*> linked = m_portOut[portS]->getLink();
866  for (int i=0; i<(int)linked.size(); i++){
867  if (linked[i] == objOut){
868  m_portOut[portS]->clear(i);
869  }
870  }
871  };
872 }
873 
880 void
882  if ( m_portIn.count(portR) != 0 ){
883  if (j<(int)m_portIn[portR]->getLink().size() && j >= 0){
884  m_portIn[portR]->clear(j);
885  }
886  }
887 }
888 
894 void
896  if ( m_portOut.count(portS) != 0 ){
897  if (j<(int)m_portOut[portS]->getLink().size() && j >= 0){
898  m_portOut[portS]->clear(j);
899  }
900  }
901 }
902 
909 
916 
917 
927 std::vector<BaseManipulation*> BaseManipulation::getSubBlocksEmbedded(){
928  return std::vector<BaseManipulation *>();
929 };
930 
931 #if MIMMO_ENABLE_MPI
932 
934 int BaseManipulation::getProcessorCount(){
935  return m_nprocs;
936 }
937 
939 int BaseManipulation::getRank(){
940  return m_rank;
941 }
943 MPI_Comm & BaseManipulation::getCommunicator(){
944  return m_communicator;
945 }
946 
947 #endif
948 
949 
955 void
957 {
958  if (getGeometry() == nullptr) return;
959  darray3E vertexcoords;
960  long int ID;
961  for (const auto & vertex : getGeometry()->getVertices()){
962  vertexcoords = vertex.getCoords();
963  ID = vertex.getId();
964  if(displacements.exists(ID)) vertexcoords += displacements[ID];
965  getGeometry()->modifyVertex(vertexcoords, ID);
966  }
967 
968  // Update geometry
969  getGeometry()->update();
970 
971 }
972 
978 void
980 {
981  //Check geometry
982  if (geometry == nullptr){
983  (*m_log) << " Warning: geometry null during writing " << m_name << std::endl;
984  return;
985  }
986 
987  bitpit::VTKUnstructuredGrid & VTK = geometry->getPatch()->getVTK();
988  VTK.setDirectory(m_outputPlot+"/");
989  VTK.setName(m_name+std::to_string(m_counter));
990  geometry->getPatch()->write();
991 }
992 
993 };
PortID findPinOut(PortOut &pin)
void addPinOut(BaseManipulation *objOut, PortID portS, PortID portR)
BaseManipulation * getChild(int i=0)
virtual void plotOptionalResults()
ConnectionType getConnectionType()
void setLog(bitpit::Logger &log)
void addParent(BaseManipulation *parent)
void setName(std::string name)
virtual void execute()=0
void removePinIn(BaseManipulation *objIn, PortID portR)
std::unordered_map< PortID, PortOut * > getPortsOut()
void setBufferIn(PortID port, mimmo::IBinaryStream &input)
void setOutputPlot(std::string path)
BaseManipulation is the base class of any manipulation object of the library.
void addPinIn(BaseManipulation *objIn, PortID portR)
BaseManipulation & operator=(const BaseManipulation &other)
void unsetChild(BaseManipulation *child)
BaseManipulation * getParent(int i=0)
bitpit::Logger & getLog()
ConnectionType
Type of allowed connections of the object: bidirectional, only input or only output.
void write(MimmoSharedPointer< MimmoObject > geometry)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
PortIn is the abstract PIN base class dedicated to carry data to a target class from other ones (inpu...
Definition: InOut.hpp:201
PortOut is the abstract PIN base class dedicated to exchange data from a target class to other ones (...
Definition: InOut.hpp:96
void addChild(BaseManipulation *child)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
MimmoSharedPointer< MimmoObject > m_geometry
bool isParent(BaseManipulation *, int &)
void initializeLogger(bool logexists)
PortID findPinIn(PortIn &pin)
std::unordered_map< PortID, PortOut * > m_portOut
void cleanBufferIn(PortID port)
void readBufferIn(PortID port)
void _apply(MimmoPiercedVector< darray3E > &displacements)
std::string PortID
Definition: InOut.hpp:32
void removePinOut(BaseManipulation *objOut, PortID portS)
void setGeometry(MimmoSharedPointer< MimmoObject > geometry)
mimmo custom derivation of bitpit IBinaryStream (see relative doc)
std::array< double, 3 > darray3E
std::unordered_map< PortID, PortIn * > m_portIn
bool isChild(BaseManipulation *, int &)
std::unordered_map< PortID, PortIn * > getPortsIn()
void setPriority(uint priority)
MimmoSharedPointer is a custom implementation of shared pointer.
MimmoSharedPointer< MimmoObject > getGeometry()
void removeAllPins(BaseManipulation *objSend, BaseManipulation *objRec)
void setApply(bool flag=true)
MimmoSharedPointer< MimmoObject > & getGeometryReference()
void swap(BaseManipulation &x) noexcept
virtual std::vector< BaseManipulation * > getSubBlocksEmbedded()
void unsetParent(BaseManipulation *parent)