ClipGeometry.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 "ClipGeometry.hpp"
25 
26 namespace mimmo{
27 
31  m_name = "mimmo.ClipGeometry";
32  m_plane.fill(0.0);
33  m_origin.fill(0.0);
34  m_normal.fill(0.0);
35  m_insideout = false;
36  m_clipped.reset();
37  m_implicit = false;
38 };
39 
44 ClipGeometry::ClipGeometry(const bitpit::Config::Section & rootXML){
45 
46  m_name = "mimmo.ClipGeometry";
47  m_plane.fill(0.0);
48  m_insideout = false;
49  m_clipped.reset();
50  m_origin.fill(0.0);
51  m_normal.fill(0.0);
52  m_implicit = false;
53 
54  std::string fallback_name = "ClassNONE";
55  std::string input = rootXML.get("ClassName", fallback_name);
56  input = bitpit::utils::string::trim(input);
57  if(input == "mimmo.ClipGeometry"){
58  absorbSectionXML(rootXML);
59  }else{
61  };
62 }
63 
67 
71  m_plane = other.m_plane;
72  m_insideout = other.m_insideout;
73  m_origin = other.m_origin;
74  m_normal = other.m_normal;
75  m_implicit = other.m_implicit;
76 };
77 
80 void
82 
83  bool built = true;
84 
85  built = (built && createPortIn<darray4E, ClipGeometry>(this, &mimmo::ClipGeometry::setClipPlane, M_PLANE));
86  built = (built && createPortIn<darray3E, ClipGeometry>(this, &mimmo::ClipGeometry::setOrigin, M_POINT));
87  built = (built && createPortIn<darray3E, ClipGeometry>(this, &mimmo::ClipGeometry::setNormal, M_AXIS));
88  built = (built && createPortIn<bool, ClipGeometry>(this, &mimmo::ClipGeometry::setInsideOut, M_VALUEB));
89  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, ClipGeometry>(this, &mimmo::ClipGeometry::setGeometry, M_GEOM, true));
90 
91  built = (built && createPortOut<MimmoSharedPointer<MimmoObject>, ClipGeometry>(this, &mimmo::ClipGeometry::getClippedPatch, M_GEOM));
92  m_arePortsBuilt = built;
93 };
94 
100 bool
102  return(m_insideout);
103 };
104 
112  return(m_clipped);
113 };
114 
120 darray4E
122  return m_plane;
123 };
124 
129 void
131  m_plane = plane;
132  m_implicit = true;
133 };
134 
141 void
143 
144  normal /= norm2(normal);
145  double b = -1.0*dotProduct(origin, normal);
146 
147  m_plane[0] = normal[0];
148  m_plane[1] = normal[1];
149  m_plane[2] = normal[2];
150  m_plane[3] = b;
151 
152  m_implicit = true;
153 
154 };
155 
161 void
163  m_origin = origin;
164 };
165 
171 void
173  m_normal = normal;
174 };
175 
182 void
184  m_insideout = flag;
185 };
186 
190 void
192 
193  if(getGeometry() == nullptr){
194  (*m_log)<<m_name + " : nullptr geometry linked."<<std::endl;
195  throw std::runtime_error (m_name + " : nullptr geometry linked.");
196  };
197 
198  /* If an implicit definition is not present it has to be computed
199  * by using origin and normal.
200  */
201  if (!m_implicit) setClipPlane(m_origin, m_normal);
202 
203  m_clipped.reset();
204 
205  livector1D extracted = clipPlane();
206 
207  /* Create subpatch.*/
209  m_clipped = temp;
210  bitpit::PatchKernel * tri = getGeometry()->getPatch();
211 
212  livector1D idVertexList = getGeometry()->getVertexFromCellList(extracted);
213 
214  temp->getPatch()->reserveVertices(idVertexList.size());
215  temp->getPatch()->reserveCells(extracted.size());
216 
217  for(long idV : idVertexList){
218  m_clipped->addVertex(tri->getVertexCoords(idV),idV);
219  }
220 
221  int rank;
222  for(long idCell : extracted){
223 
224  bitpit::Cell & cell = tri->getCell(idCell);
225  rank =-1;
226 #if MIMMO_ENABLE_MPI
227  rank = getGeometry()->getPatch()->getCellRank(idCell);
228 #endif
229  m_clipped->addCell(cell, idCell, rank);
230  }
231  //MPI version: recovering info from the local rank partition
232  auto originalmap = getGeometry()->getPIDTypeListWNames();
233  auto currentPIDmap = temp->getPIDTypeList();
234  for(const auto & val: currentPIDmap){
235  m_clipped->setPIDName(val, originalmap[val]);
236  }
237 
238  // Clean and Update mesh. This will update even parallel structures if needed
239  m_clipped->cleanGeometry();
240  m_clipped->update();
241 
242 };
243 
251 ClipGeometry::clipPlane(){
252 
253  livector1D result;
254  darray3E norm;
255  double offset;
256  int counter;
257  double sig = 1.0 - 2.0*(int)isInsideOut();
258  long iD;
259 
260 
261  for(int i=0; i<3; ++i)norm[i] = m_plane[i];
262  offset = m_plane[3];
263 
264  double normPlane = norm2(norm);
265  if(normPlane < 1.E-18)return result;
266  norm /= normPlane;
267 
268  bitpit::PatchKernel * tri = getGeometry()->getPatch();
269 
270  if(getGeometry()->getType() == 3){
271  counter = 0;
272  result.resize(tri->getVertexCount());
273  for(const auto vert : tri->getVertices()){
274  iD = vert.getId();
275  if(sig*(dotProduct(norm, vert.getCoords()) + offset) >0){
276  result[counter] = iD;
277  ++counter;
278  }
279  }
280 
281  }else{
282  counter = 0;
283  result.resize(tri->getCellCount());
284  for(const auto cell : tri->getCells()){
285  iD = cell.getId();
286  if(sig*(dotProduct(norm, tri->evalCellCentroid(iD)) + offset) >0){
287  result[counter] = iD;
288  ++counter;
289  }
290  }
291  }
292  result.resize(counter);
293  return result;
294 };
295 
300 void
302 
304 
305 }
306 
312 void
313 ClipGeometry::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
314 
315  /*start absorbing*/
316  BITPIT_UNUSED(name);
317 
319 
320  if(slotXML.hasOption("InsideOut")){
321  std::string input = slotXML.get("InsideOut");
322  input = bitpit::utils::string::trim(input);
323  bool value = false;
324  if(!input.empty()){
325  std::stringstream ss(input);
326  ss >> value;
327  }
328  setInsideOut(value);
329  }
330 
331  if(slotXML.hasSection("ClipPlane")){
332  const bitpit::Config::Section & planeXML = slotXML.getSection("ClipPlane");
333 
334  std::string input1 = planeXML.get("Point");
335  std::string input2 = planeXML.get("Normal");
336  input1 = bitpit::utils::string::trim(input1);
337  input2 = bitpit::utils::string::trim(input2);
338 
339  darray3E temp1 = {{0.0,0.0,0.0}};
340  darray3E temp2 = {{0.0,0.0,0.0}};
341 
342  if(!input1.empty()){
343  std::stringstream ss(input1);
344  ss>>temp1[0]>>temp1[1]>>temp1[2];
345  }
346  if(!input2.empty()){
347  std::stringstream ss(input2);
348  ss>>temp2[0]>>temp2[1]>>temp2[2];
349  }
350 
351  setClipPlane(temp1, temp2);
352  };
353 };
354 
360 void
361 ClipGeometry::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
362 
363  BITPIT_UNUSED(name);
364 
365  BaseManipulation::flushSectionXML(slotXML, name);
366 
367  int value = m_insideout;
368  slotXML.set("InsideOut", std::to_string(value));
369 
370  {
371  darray4E org = getClipPlane();
372  darray3E normal;
373  darray3E point = {{0.0,0.0,0.0}};
374  int imax = -1;
375  double dum = 0.0;
376  for(int i=0; i<3; ++i){
377  normal[i] =org[i];
378  if(abs(normal[i]) > dum) {
379  imax = i;
380  dum = abs(normal[i]);
381  }
382  }
383  if(imax != -1)point[imax] = -1.0*org[3]/normal[imax];
384 
385  std::stringstream ss1, ss2;
386  ss1<<std::scientific<<point[0]<<'\t'<<point[1]<<'\t'<<point[2];
387  ss2<<std::scientific<<normal[0]<<'\t'<<normal[1]<<'\t'<<normal[2];
388 
389  bitpit::Config::Section & planeXML = slotXML.addSection("ClipPlane");
390  planeXML.set("Point",ss1.str());
391  planeXML.set("Normal",ss2.str());
392  }
393 
394 };
395 
396 }
std::array< double, 4 > darray4E
MimmoObject is the basic geometry container for mimmo library.
#define M_GEOM
void setOrigin(darray3E origin)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
std::vector< long > livector1D
void setClipPlane(darray4E plane)
#define M_POINT
void warningXML(bitpit::Logger *log, std::string name)
BaseManipulation is the base class of any manipulation object of the library.
virtual void plotOptionalResults()
MimmoSharedPointer< MimmoObject > getClippedPatch()
void write(MimmoSharedPointer< MimmoObject > geometry)
void setInsideOut(bool flag)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
#define M_PLANE
ClipGeometry is a class that clip a 3D geometry according to a plane intersecting it.
void setGeometry(MimmoSharedPointer< MimmoObject > geometry)
std::array< double, 3 > darray3E
void setNormal(darray3E normal)
#define M_AXIS
MimmoSharedPointer is a custom implementation of shared pointer.
MimmoSharedPointer< MimmoObject > getGeometry()
#define M_VALUEB