ControlDeformMaxDistance.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 "ControlDeformMaxDistance.hpp"
25 #include "SkdTreeUtils.hpp"
26 
27 namespace mimmo{
28 
29 
33  m_name = "mimmo.ControlDeformMaxDistance";
34  m_maxDist= 0.0 ;
35 
36 };
37 
42 ControlDeformMaxDistance::ControlDeformMaxDistance(const bitpit::Config::Section & rootXML){
43 
44  m_name = "mimmo.ControlDeformMaxDistance";
45  m_maxDist= 0.0 ;
46 
47  std::string fallback_name = "ClassNONE";
48  std::string input = rootXML.get("ClassName", fallback_name);
49  input = bitpit::utils::string::trim(input);
50  if(input == "mimmo.ControlDeformMaxDistance"){
51  absorbSectionXML(rootXML);
52  }else{
54  };
55 }
56 
60 
65  m_maxDist = other.m_maxDist;
66 };
67 
73  swap(other);
74  return(*this);
75 };
76 
82 {
83  std::swap(m_maxDist, x.m_maxDist);
84  m_violationField.swap(x.m_violationField);
85  m_defField.swap(x.m_defField);
87 }
88 
91 void
93  bool built = true;
94 
95  built = (built && createPortIn<dmpvecarr3E*, ControlDeformMaxDistance>(this, &mimmo::ControlDeformMaxDistance::setDefField, M_GDISPLS));
96  built = (built && createPortIn<double, ControlDeformMaxDistance>(this, &mimmo::ControlDeformMaxDistance::setLimitDistance, M_VALUED));
97  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, ControlDeformMaxDistance>(this, &mimmo::ControlDeformMaxDistance::setGeometry, M_GEOM, true));
98 
99  built = (built && createPortOut<double, ControlDeformMaxDistance>(this, &mimmo::ControlDeformMaxDistance::getViolation, M_VALUED));
100  built = (built && createPortOut<dmpvector1D*, ControlDeformMaxDistance>(this, &mimmo::ControlDeformMaxDistance::getViolationField, M_SCALARFIELD));
101  m_arePortsBuilt = built;
102 };
103 
111 double
113 
114  double result = -1.0*std::numeric_limits<double>::max();
115  for(const auto & val : m_violationField){
116  result = std::fmax(result, val);
117  }
118 #if MIMMO_ENABLE_MPI
119  MPI_Allreduce(MPI_IN_PLACE, &result, 1, MPI_DOUBLE, MPI_MAX, m_communicator);
120 #endif
121  return result;
122 };
123 
124 
132 dmpvector1D *
134  return &m_violationField;
135 };
136 
142 void
144  if(!field) return;
145  m_defField.clear();
146  m_violationField.clear();
147  m_defField = *field;
148 };
149 
155 void
157  m_maxDist = std::fmax(1.0E-12,dist);
158 };
159 
165 void
167  if (geo == nullptr) return;
168  if (geo->getType() != 1 ) return;
169 
171 }
172 
175 void
177 
179  if(geo == nullptr){
180  (*m_log)<<"Error "+m_name + " : null pointer to linked geometry found"<<std::endl;
181  throw std::runtime_error("Error "+m_name + " : null pointer to linked geometry found");
182  }
183 
184  if(geo->isEmpty()){
185  (*m_log)<<"Warning in " + m_name + " : empty linked geometry found"<<std::endl;
186  }
187 
188  bool check = m_defField.getGeometry() == geo;
189  check = check && m_defField.getDataLocation() == MPVLocation::POINT;
190  if(!check){
191  (*m_log)<<"Warning in "<<m_name<<": Unsuitable deformation field linked"<<std::endl;
192  }
193  m_defField.completeMissingData({{0.0,0.0,0.0}});
194 
195  geo->buildSkdTree();
196 
197  m_violationField.clear();
198  m_violationField.initialize(geo, MPVLocation::POINT, -1.0*std::numeric_limits<double>::max());
199 
200  std::vector<long> mapIDV = geo->getVerticesIds(); //take all internals and ghosts if partitioned mesh.
201  //set points structure
202  std::vector<std::array<double,3> > points;
203  std::vector<double> normDef;
204  points.reserve(mapIDV.size());
205  normDef.resize(mapIDV.size(), 1.0E-08);
206 
207  int counter = 0;
208  for (long idV : mapIDV){
209  points.push_back(geo->getVertexCoords(idV) + m_defField[idV] );
210  normDef[counter] = std::max(normDef[counter], 1.2*norm2(m_defField[idV]) );
211  ++counter;
212  }
213 
214  std::vector<double> distances(mapIDV.size());
215  std::vector<long> suppCellIds(mapIDV.size());
216 
217 #if MIMMO_ENABLE_MPI
218  std::vector<int> suppCellRanks(mapIDV.size());
219  skdTreeUtils::globalDistance(points.size(), points.data(), geo->getSkdTree(), suppCellIds.data(), suppCellRanks.data(), distances.data(), normDef.data(), false);
220 #else
221  skdTreeUtils::distance(points.size(), points.data(), geo->getSkdTree(), suppCellIds.data(), distances.data(), normDef.data());
222 #endif
223  //transfer distance value inside m_violation field.(parallel case, ghost are already in)
224  //Final value of violation is local distance of deformed point minus the offset m_maxDist
225  // fixed by the user
226  counter = 0;
227  for( long id : mapIDV){
228  m_violationField[id] = (distances[counter] - m_maxDist);
229  ++counter;
230  }
231 
232 
233  double violationMax = getViolation();
234  //write resume file: in case of parallel version, only rank 0 writes.
235 #if MIMMO_ENABLE_MPI
236  if(m_rank == 0){
237 #endif
238  std::string logname = m_name+std::to_string(getId())+"_violation.log";
239  std::ofstream log;
240  log.open(logname);
241  log<<"mimmo "<<m_name<<" resume file"<<std::endl;
242  log<<std::endl;
243  log<<std::endl;
244  log<<" violation value : " << violationMax << std::endl;
245  log.close();
246 
247 #if MIMMO_ENABLE_MPI
248  }
249  MPI_Barrier(m_communicator); // other ranks stalled here, waiting 0 to finish writing.
250 #endif
251 
252 };
253 
259 void
260 ControlDeformMaxDistance::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
261 
262  BITPIT_UNUSED(name);
263 
264  //start absorbing
265  BaseManipulation::absorbSectionXML(slotXML, name);
266 
267  if(slotXML.hasOption("LimitDistance")){
268  std::string input = slotXML.get("LimitDistance");
269  input = bitpit::utils::string::trim(input);
270  double value = 0.0;
271  if(!input.empty()){
272  std::stringstream ss(input);
273  ss >> value;
274  }
275  setLimitDistance(value);
276  }
277 };
278 
284 void
285 ControlDeformMaxDistance::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
286 
287  BITPIT_UNUSED(name);
288 
289  BaseManipulation::flushSectionXML(slotXML, name);
290 
291  slotXML.set("LimitDistance", std::to_string(m_maxDist));
292 
293 };
294 
299 void
301 
302  m_defField.setName("Deformation Field");
303  m_violationField.setName("Violation Distance Field");
304  write(getGeometry(), m_defField, m_violationField);
305 
306 }
307 
308 
309 
310 }
#define M_GDISPLS
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
#define M_GEOM
void swap(ControlDeformMaxDistance &x) noexcept
ControlDeformMaxDistance & operator=(ControlDeformMaxDistance other)
void setName(std::string name)
bool completeMissingData(const mpv_t &defValue)
void warningXML(bitpit::Logger *log, std::string name)
BaseManipulation is the base class of any manipulation object of the library.
MimmoSharedPointer< MimmoObject > getGeometry() const
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
void write(MimmoSharedPointer< MimmoObject > geometry)
ControlDeformMaxDistance is a class that check a deformation field associated to a MimmoObject surfac...
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
void initialize(MimmoSharedPointer< MimmoObject >, MPVLocation, const mpv_t &)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
#define M_VALUED
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
#define M_SCALARFIELD
void setGeometry(MimmoSharedPointer< MimmoObject > geometry)
MimmoSharedPointer is a custom implementation of shared pointer.
MimmoSharedPointer< MimmoObject > getGeometry()
void swap(BaseManipulation &x) noexcept
double distance(const std::array< double, 3 > *point, const bitpit::PatchSkdTree *tree, long &id, double r)