AABBox.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 "AABBox.hpp"
26 
27 namespace mimmo{
28 
31  m_name = "mimmo.AABBox";
32  m_origin.fill(0.0);
33  m_span.fill(1.0);
34  int counter = 0;
35  for(auto &val : m_axes) {
36  val.fill(0.0);
37  val[counter] = 1.0;
38  ++counter;
39  }
40  m_writeInfo = false;
41 };
42 
47 AABBox::AABBox(const bitpit::Config::Section & rootXML){
48 
49  m_name = "mimmo.AABBox";
50  m_origin.fill(0.0);
51  m_span.fill(1.0);
52  int counter = 0;
53  for(auto &val : m_axes) {
54  val.fill(0.0);
55  val[counter] = 1.0;
56  ++counter;
57  }
58  m_writeInfo = false;
59 
60  std::string fallback_name = "ClassNONE";
61  std::string input = rootXML.get("ClassName", fallback_name);
62  input = bitpit::utils::string::trim(input);
63  if(input == "mimmo.AABBox"){
64  absorbSectionXML(rootXML);
65  }else{
67  };
68 }
69 
72 
76 AABBox::AABBox(const AABBox & other):BaseManipulation(other){
77  m_origin = other.m_origin;
78  m_span = other.m_span;
79  m_axes = other.m_axes;
80  m_listgeo = other.m_listgeo;
81  m_writeInfo = other.m_writeInfo;
82 };
83 
88 void AABBox::swap(AABBox & x) noexcept
89 {
90  std::swap(m_origin, x.m_origin);
91  std::swap(m_span, x.m_span);
92  std::swap(m_axes, x.m_axes);
93  std::swap(m_listgeo, x.m_listgeo);
94  std::swap(m_writeInfo, x.m_writeInfo);
95 
97 }
100 void
102 
103  bool built = true;
104  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, AABBox>(this, &mimmo::AABBox::setGeometry, M_GEOM,true,1));
105  built = (built && createPortIn<std::vector<MimmoSharedPointer<MimmoObject> >, AABBox>(this, &mimmo::AABBox::setGeometries, M_VECGEOM, true,1));
106  built = (built && createPortIn<dmatrix33E, AABBox>(this, &mimmo::AABBox::setAxes, M_AXES));
107  built = (built && createPortOut<darray3E, AABBox>(this, &mimmo::AABBox::getOrigin, M_POINT));
108  built = (built && createPortOut<dmatrix33E, AABBox>(this, &mimmo::AABBox::getAxes, M_AXES));
109  built = (built && createPortOut<darray3E, AABBox>(this, &mimmo::AABBox::getSpan, M_SPAN));
110 
111  m_arePortsBuilt = built;
112 };
113 
115 void
117  clear(); //base manipulation stuff clear
118  m_origin.fill(0.0);
119  m_span.fill(1.0);
120  m_listgeo.clear();
121  int counter = 0;
122  for(auto &val : m_axes) {
123  val.fill(0.0);
124  val[counter] = 1.0;
125  ++counter;
126  }
127  m_writeInfo = false;
128 };
129 
133 darray3E
135  return(m_origin);
136 }
137 
141 darray3E
143  return(m_span);
144 }
145 
146 
152 
153  return(m_axes);
154 }
155 
156 
160 std::vector<MimmoSharedPointer<MimmoObject> >
162  std::vector<MimmoSharedPointer<MimmoObject> > result;
163  result.reserve(m_listgeo.size());
164  for(auto pp: m_listgeo)
165  result.push_back(pp.first);
166  return result;
167 };
168 
169 
174 void
176  m_listgeo.clear();
177  for( auto val : listgeo){
178  setGeometry(val);
179  }
180 };
181 
187 void
189 
190  if (geo == nullptr) {
191  (*m_log)<<"warning: "<<m_name<<" not valid Geometry pointer. Doing nothing"<<std::endl;
192  return;
193  }
194 
195  m_listgeo.insert(std::make_pair(geo, geo->getType()));
196 };
197 
198 
203 void
205  m_axes = axes;
206 }
207 
212 void
214  m_writeInfo = flag;
215 }
216 
223 void
224 AABBox::plot(std::string directory, std::string filename,int counter, bool binary){
225 
226 
227  dvecarr3E activeP(8);
228 
229  activeP[0] = - 0.5 * m_span;
230  activeP[6] = 0.5 * m_span;
231 
232  activeP[1] = activeP[0]; activeP[1][0] += m_span[0];
233  activeP[3] = activeP[0]; activeP[3][1] += m_span[1];
234  activeP[2] = activeP[6]; activeP[2][2] += -1.0*m_span[2];
235 
236  activeP[7] = activeP[6]; activeP[7][0] += -1.0*m_span[0];
237  activeP[5] = activeP[6]; activeP[5][1] += -1.0*m_span[1];
238  activeP[4] = activeP[0]; activeP[4][2] += m_span[2];
239 
240  darray3E temp;
241  dmatrix33E inv = inverse(m_axes);
242  for(auto &val : activeP){
243  for(int i=0; i<3; ++i){
244  temp[i] = dotProduct(val, inv[i]);
245  }
246  val = temp + m_origin;
247  }
248 
249  ivector2D activeConn(1);
250  for(int i=0; i<8; ++i) activeConn[0].push_back(i);
251 
252  bitpit::VTKFormat codex = bitpit::VTKFormat::ASCII;
253  if(binary){codex=bitpit::VTKFormat::APPENDED;}
254  bitpit::VTKElementType elDM = bitpit::VTKElementType::HEXAHEDRON;
255  bitpit::VTKUnstructuredGrid vtk(directory, filename, elDM);
256  vtk.setGeomData( bitpit::VTKUnstructuredField::POINTS, activeP) ;
257  vtk.setGeomData( bitpit::VTKUnstructuredField::CONNECTIVITY, activeConn) ;
258  vtk.setDimensions(1, 8);
259  vtk.setCodex(codex);
260  if(counter>=0){vtk.setCounter(counter);}
261 
262  vtk.write();
263 };
264 
265 
269 void
271 
272  // check if the list is empty.
273  if(m_listgeo.empty()){
274  m_span.fill(0.0);
275  m_origin.fill(0.0);
276  return;
277  };
278 
279  //check sdr;
280  {
281  double normx1= norm2(m_axes[0]);
282  double normx2= norm2(m_axes[1]);
283  double tol = std::numeric_limits<double>::min();
284  if (normx1 > tol && normx2 > tol){
285  m_axes[0] /= normx1;
286  m_axes[1] /= normx2;
287  }else{
288  m_axes[0] = {{0,0,1}};
289  m_axes[1] = {{0,1,0}};
290  }
291 
292  m_axes[2] = crossProduct(m_axes[0], m_axes[1]);
293  }
294 
295  darray3E pmin, pmax;
296  pmin.fill(std::numeric_limits<double>::max());
297  pmax.fill(-1.0*std::numeric_limits<double>::max());
298  double val;
299 
300  for(auto ptr : getGeometries()){
301  for(auto & vert: ptr->getVertices()){
302  darray3E coord = vert.getCoords();
303  for(int i=0;i<3; ++i){
304  val = dotProduct(coord, m_axes[i]);
305  pmin[i] = std::fmin(pmin[i], val);
306  pmax[i] = std::fmax(pmax[i], val);
307  }
308  }
309  }
310 
311 #if MIMMO_ENABLE_MPI
312  MPI_Allreduce(MPI_IN_PLACE, pmin.data(), 3, MPI_DOUBLE, MPI_MIN, m_communicator);
313  MPI_Allreduce(MPI_IN_PLACE, pmax.data(), 3, MPI_DOUBLE, MPI_MAX, m_communicator);
314 #endif
315 
316  dmatrix33E inv = inverse(m_axes);
317  m_span = pmax - pmin;
318  //check if one of the span goes to 0;
319  double avg_span = 0.0;
320  for(auto & val: m_span) avg_span+=val;
321  avg_span /= 3.0;
322 
323  for(auto &val : m_span) {
324  val = std::fmax(val, 1.E-04*avg_span);
325  }
326 
327  darray3E originLoc = 0.5*(pmin+pmax);
328  for(int i=0; i<3; ++i){
329  m_origin[i] = dotProduct(originLoc, inv[i]);
330  }
331 
332 
333  if (m_writeInfo){
334 
335  std::ofstream out;
336  out.open(m_outputPlot+"/"+m_name+std::to_string(getId())+"_INFO.dat");
337  if(out.is_open()){
338  out<<"AABBox "<<std::to_string(getId())<<" info:"<<std::endl;
339  out<<std::endl;
340  out<<std::endl;
341  out<<"Origin: "<<std::scientific<<m_origin<<std::endl;
342  out<<std::endl;
343  out<<"Axis 0: "<<std::scientific<<m_axes[0]<<std::endl;
344  out<<"Axis 1: "<<std::scientific<<m_axes[1]<<std::endl;
345  out<<"Axis 2: "<<std::scientific<<m_axes[2]<<std::endl;
346  out<<std::endl;
347  out<<"Span: "<<std::scientific<<m_span<<std::endl;
348 
349  out.close();
350  }
351  }
352 };
353 
358 void
360  std::string dir = m_outputPlot ;
361  std::string nameGrid = m_name;
362  plot(dir, nameGrid, getId(), true );
363 }
364 
370 void
371 AABBox::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
372 
373  BITPIT_UNUSED(name);
374  BaseManipulation::absorbSectionXML(slotXML, name);
375 
376  if(slotXML.hasOption("WriteInfo")){
377  std::string input = slotXML.get("WriteInfo");
378  input = bitpit::utils::string::trim(input);
379  bool value = false;
380  if(!input.empty()){
381  std::stringstream ss(input);
382  ss >> value;
383  }
384  setWriteInfo(value);
385  }
386 
387  if(slotXML.hasSection("Axes")){
388 
389  const bitpit::Config::Section & axesXML = slotXML.getSection("Axes");
390  dmatrix33E axes;
391  for(int i=0; i<3; ++i){
392  axes[i].fill(0.0);
393  axes[i][i] = 1.0;
394  }
395 
396  if(axesXML.hasOption("axis0")){
397  std::string input = axesXML.get("axis0");
398  input = bitpit::utils::string::trim(input);
399  if(!input.empty()){
400  std::stringstream ss(input);
401  ss>>axes[0][0]>>axes[0][1]>>axes[0][2];
402  }
403  }
404 
405  if(axesXML.hasOption("axis1")){
406  std::string input = axesXML.get("axis1");
407  input = bitpit::utils::string::trim(input);
408  if(!input.empty()){
409  std::stringstream ss(input);
410  ss>>axes[1][0]>>axes[1][1]>>axes[1][2];
411  }
412  }
413 
414  if(axesXML.hasOption("axis2")){
415  std::string input = axesXML.get("axis2");
416  input = bitpit::utils::string::trim(input);
417  if(!input.empty()){
418  std::stringstream ss(input);
419  ss>>axes[2][0]>>axes[2][1]>>axes[2][2];
420  }
421  }
422 
423  setAxes(axes);
424  }
425 }
426 
432 void
433 AABBox::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
434 
435  BITPIT_UNUSED(name);
436  BaseManipulation::flushSectionXML(slotXML, name);
437 
438  slotXML.set("WriteInfo", std::to_string((int)m_writeInfo));
439  {
440  dmatrix33E axes = getAxes();
441  bitpit::Config::Section & axesXML = slotXML.addSection("Axes");
442 
443  for(int i=0; i<3; ++i){
444  std::string name = "axis"+std::to_string(i);
445  std::stringstream ss;
446  ss<<std::scientific<<axes[i][0]<<'\t'<<axes[i][1]<<'\t'<<axes[i][2];
447  axesXML.set(name, ss.str());
448  }
449  }
450 };
451 
458  dmatrix33E out;
459 
460  for(std::size_t i=0; i<3; ++i){
461  for(std::size_t j=0; j<3; ++j){
462  out[j][i] = mat[i][j];
463  }
464  }
465  return out;
466 }
467 
474  dmatrix33E out;
475 
476  double det = mat[0][0] * (mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2]) -
477  mat[0][1] * (mat[1][0]*mat[2][2] - mat[2][0]*mat[1][2]) +
478  mat[0][2] * (mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1]);
479 
480  out[0][0] = (mat[1][1]*mat[2][2] - mat[2][1]*mat[1][2])/det;
481  out[0][1] = (mat[0][2]*mat[2][1] - mat[2][2]*mat[0][1])/det;
482  out[0][2] = (mat[0][1]*mat[1][2] - mat[1][1]*mat[0][2])/det;
483  out[1][0] = (mat[1][2]*mat[2][0] - mat[2][2]*mat[1][0])/det;
484  out[1][1] = (mat[0][0]*mat[2][2] - mat[2][0]*mat[0][2])/det;
485  out[1][2] = (mat[0][2]*mat[1][0] - mat[1][2]*mat[0][0])/det;
486  out[2][0] = (mat[1][0]*mat[2][1] - mat[2][0]*mat[1][1])/det;
487  out[2][1] = (mat[0][1]*mat[2][0] - mat[2][1]*mat[0][0])/det;
488  out[2][2] = (mat[0][0]*mat[1][1] - mat[1][0]*mat[0][1])/det;
489 
490 
491  return out;
492 }
493 }
virtual ~AABBox()
Definition: AABBox.cpp:71
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
Definition: AABBox.cpp:433
darray3E getOrigin()
Definition: AABBox.cpp:134
dmatrix33E m_axes
Definition: AABBox.hpp:89
std::unordered_map< MimmoSharedPointer< MimmoObject >, int > m_listgeo
Definition: AABBox.hpp:91
#define M_GEOM
darray3E m_span
Definition: AABBox.hpp:88
void setGeometries(std::vector< MimmoSharedPointer< MimmoObject > > listgeo)
Definition: AABBox.cpp:175
std::vector< darray3E > dvecarr3E
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
Definition: AABBox.cpp:188
void clearAABBox()
Definition: AABBox.cpp:116
void swap(AABBox &x) noexcept
Definition: AABBox.cpp:88
#define M_POINT
void warningXML(bitpit::Logger *log, std::string name)
Axis Aligned Bounding Box calculator.
Definition: AABBox.hpp:84
BaseManipulation is the base class of any manipulation object of the library.
darray3E getSpan()
Definition: AABBox.cpp:142
void buildPorts()
Definition: AABBox.cpp:101
virtual void plotOptionalResults()
Definition: AABBox.cpp:359
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
Definition: AABBox.cpp:371
void plot(std::string directory, std::string filename, int counter, bool binary)
Definition: AABBox.cpp:224
darray3E m_origin
Definition: AABBox.hpp:87
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
dmatrix33E getAxes()
Definition: AABBox.cpp:151
dmatrix33E inverse(const dmatrix33E &mat)
Definition: AABBox.cpp:473
std::array< darray3E, 3 > dmatrix33E
std::vector< MimmoSharedPointer< MimmoObject > > getGeometries()
Definition: AABBox.cpp:161
#define M_SPAN
void setWriteInfo(bool flag)
Definition: AABBox.cpp:213
#define M_AXES
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
dmatrix33E transpose(const dmatrix33E &mat)
Definition: AABBox.cpp:457
void setAxes(dmatrix33E axes)
Definition: AABBox.cpp:204
std::vector< ivector1D > ivector2D
void execute()
Definition: AABBox.cpp:270
bool m_writeInfo
Definition: AABBox.hpp:92
std::array< double, 3 > darray3E
MimmoSharedPointer is a custom implementation of shared pointer.
void swap(BaseManipulation &x) noexcept
#define M_VECGEOM