TwistGeometry.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 "TwistGeometry.hpp"
25 
26 namespace mimmo{
27 
28 
33  m_origin = origin;
34  m_direction = direction;
35  m_sym = false;
36  m_alpha = 0.0;
37  m_distance = 0.0;
38  m_name = "mimmo.TwistGeometry";
39 };
40 
45 TwistGeometry::TwistGeometry(const bitpit::Config::Section & rootXML){
46 
47  m_origin.fill(0.0);
48  m_direction.fill(0.0);
49  m_alpha = 0.0;
50  m_distance = 0.0;
51  m_sym = false;
52  m_name = "mimmo.TwistGeometry";
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.TwistGeometry"){
58  absorbSectionXML(rootXML);
59  }else{
61  };
62 }
63 
67 
71  m_origin = other.m_origin;
72  m_direction = other.m_direction;
73  m_alpha = other.m_alpha;
74  m_distance = other.m_distance;
75  m_sym = other.m_sym;
76  m_filter = other.m_filter;
77 };
78 
82  swap(other);
83  return *this;
84 };
85 
90 {
91  std::swap(m_origin, x.m_origin);
92  std::swap(m_direction, x.m_direction);
93  std::swap(m_alpha, x.m_alpha);
94  std::swap(m_distance, x.m_distance);
95  std::swap(m_sym, x.m_sym);
96  m_filter.swap(x.m_filter);
97  m_displ.swap(x.m_displ);
99 };
100 
103 void
105  bool built = true;
106  built = (built && createPortIn<darray3E, TwistGeometry>(&m_origin, M_POINT));
107  built = (built && createPortIn<darray3E, TwistGeometry>(&m_direction, M_AXIS));
108  built = (built && createPortIn<double, TwistGeometry>(&m_alpha, M_VALUED));
109  built = (built && createPortIn<double, TwistGeometry>(&m_distance, M_VALUED2));
110  built = (built && createPortIn<dmpvector1D*, TwistGeometry>(this, &mimmo::TwistGeometry::setFilter, M_FILTER));
111  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, TwistGeometry>(&m_geometry, M_GEOM, true));
112  built = (built && createPortOut<dmpvecarr3E*, TwistGeometry>(this, &mimmo::TwistGeometry::getDisplacements, M_GDISPLS));
113  built = (built && createPortOut<MimmoSharedPointer<MimmoObject>, TwistGeometry>(this, &BaseManipulation::getGeometry, M_GEOM));
114  m_arePortsBuilt = built;
115 };
116 
121 void
123  m_origin = origin;
124  m_direction = direction;
125 }
126 
130 void
132  m_origin = origin;
133 }
134 
138 void
140  m_direction = direction;
141  double L = norm2(m_direction);
142  for (int i=0; i<3; i++)
143  m_direction[i] /= L;
144 }
145 
149 void
151  m_alpha = alpha;
152 }
153 
157 void
159  m_sym = sym;
160 }
161 
165 void
167  m_distance = distance;
168 }
169 
174 void
176  if(!filter) return;
177  m_filter = *filter;
178 }
179 
186  return &m_displ;
187 };
188 
193 void
195 
196  if(getGeometry() == nullptr){
197  (*m_log)<<m_name + " : nullptr pointer to linked geometry found"<<std::endl;
198  throw std::runtime_error(m_name + "nullptr pointer to linked geometry found");
199  }
200 
201  checkFilter();
202 
203  m_displ.clear();
205  m_displ.reserve(getGeometry()->getNVertices());
206  m_displ.setGeometry(getGeometry());
207 
208  darray3E point, rotated;
209  long ID;
210  darray3E projected;
211  double distance;
212  //double sign;
213  double rot;
214  darray3E value;
215 
216  for (const auto & vertex : m_geometry->getVertices()){
217  point = vertex.getCoords();
218  ID = vertex.getId();
219 
220  //signed distance from origin
221  distance = dotProduct((point-m_origin),m_direction);
222 
223  //compute coefficients and constant vectors of rodriguez formula
224  rot = std::min(m_alpha, (std::abs(distance)/m_distance)*m_alpha);
225  if (distance < 0) rot = -rot*int(m_sym);
226  double a = cos(rot);
227  darray3E b = (1 - cos(rot)) * m_direction;
228  double c = sin(rot);
229 
230  //project point on axis (local origin)
231  projected = distance*m_direction + m_origin;
232 
233 
234  point -= projected;
235  //rodrigues formula
236  rotated = a * point +
237  b * dotProduct(m_direction, point) +
238  c * crossProduct(m_direction, point);
239 
240  rotated += projected;
241  point += projected;
242 
243  value = (rotated-point)*m_filter[ID];
244  m_displ.insert(ID, value);
245 
246  }
247 };
248 
252 void
254  _apply(m_displ);
255 }
256 
261 void
263 
264  bool check = m_filter.getDataLocation() == mimmo::MPVLocation::POINT;
265  check = check && m_filter.completeMissingData(0.0);
266  check = check && m_filter.getGeometry() == getGeometry();
267 
268  if (!check){
269  m_log->setPriority(bitpit::log::Verbosity::DEBUG);
270  (*m_log)<<"Not valid filter found in "<<m_name<<". Proceeding with default unitary field"<<std::endl;
271  m_log->setPriority(bitpit::log::Verbosity::NORMAL);
272 
273  m_filter.clear();
274  m_filter.setGeometry(m_geometry);
276  m_filter.reserve(getGeometry()->getNVertices());
277  for (const auto & vertex : getGeometry()->getVertices()){
278  m_filter.insert(vertex.getId(), 1.0);
279  }
280  }
281 }
282 
288 void
289 TwistGeometry::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
290 
291  BITPIT_UNUSED(name);
292 
293  BaseManipulation::absorbSectionXML(slotXML, name);
294 
295  if(slotXML.hasOption("Origin")){
296  std::string input = slotXML.get("Origin");
297  input = bitpit::utils::string::trim(input);
298  darray3E temp = {{0.0,0.0,0.0}};
299  if(!input.empty()){
300  std::stringstream ss(input);
301  for(auto &val : temp) ss>>val;
302  }
303  setOrigin(temp);
304  }
305 
306  if(slotXML.hasOption("Direction")){
307  std::string input = slotXML.get("Direction");
308  input = bitpit::utils::string::trim(input);
309  darray3E temp = {{0.0,0.0,0.0}};
310  if(!input.empty()){
311  std::stringstream ss(input);
312  for(auto &val : temp) ss>>val;
313  }
314  setDirection(temp);
315  }
316 
317  if(slotXML.hasOption("Twist")){
318  std::string input = slotXML.get("Twist");
319  input = bitpit::utils::string::trim(input);
320  double temp = 0.0;
321  if(!input.empty()){
322  std::stringstream ss(input);
323  ss>>temp;
324  }
325  setTwist(temp);
326  }
327 
328  if(slotXML.hasOption("Distance")){
329  std::string input = slotXML.get("Distance");
330  input = bitpit::utils::string::trim(input);
331  double temp = 0.0;
332  if(!input.empty()){
333  std::stringstream ss(input);
334  ss>>temp;
335  }
336  setMaxDistance(temp);
337  }
338 
339  if(slotXML.hasOption("Symmetric")){
340  std::string input = slotXML.get("Symmetric");
341  input = bitpit::utils::string::trim(input);
342  bool temp = false;
343  if(!input.empty()){
344  std::stringstream ss(input);
345  ss>>temp;
346  }
347  setSym(temp);
348  };
349 
350 };
351 
357 void
358 TwistGeometry::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
359 
360  BITPIT_UNUSED(name);
361 
362  BaseManipulation::flushSectionXML(slotXML, name);
363 
364  {
365  std::stringstream ss;
366  ss<<std::scientific<<m_origin[0]<<'\t'<<m_origin[1]<<'\t'<<m_origin[2];
367  slotXML.set("Origin", ss.str());
368  }
369 
370  {
371  std::stringstream ss;
372  ss<<std::scientific<<m_direction[0]<<'\t'<<m_direction[1]<<'\t'<<m_direction[2];
373  slotXML.set("Direction", ss.str());
374  }
375 
376  slotXML.set("Twist", std::to_string(m_alpha));
377 
378  slotXML.set("Distance", std::to_string(m_distance));
379 
380  slotXML.set("Symmetric", std::to_string(int(m_sym)));
381 
382 };
383 
384 }
#define M_GDISPLS
void setMaxDistance(double distance)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
void setAxis(darray3E origin, darray3E direction)
TwistGeometry(darray3E origin={ {0, 0, 0} }, darray3E direction={ {0, 0, 0} })
#define M_GEOM
void setSym(bool sym)
void setDirection(darray3E direction)
#define M_VALUED2
dmpvecarr3E * getDisplacements()
bool completeMissingData(const mpv_t &defValue)
#define M_POINT
void warningXML(bitpit::Logger *log, std::string name)
BaseManipulation is the base class of any manipulation object of the library.
TwistGeometry & operator=(TwistGeometry other)
MimmoSharedPointer< MimmoObject > getGeometry() const
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="")
MimmoSharedPointer< MimmoObject > m_geometry
#define M_VALUED
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
void _apply(MimmoPiercedVector< darray3E > &displacements)
void setDataLocation(MPVLocation loc)
void setTwist(double alpha)
void setFilter(dmpvector1D *filter)
std::array< double, 3 > darray3E
#define M_AXIS
void swap(TwistGeometry &x) noexcept
void setOrigin(darray3E origin)
MimmoSharedPointer< MimmoObject > getGeometry()
TwistGeometry is the class that applies a twist to a given geometry patch.
void swap(BaseManipulation &x) noexcept
#define M_FILTER