BendGeometry.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 "BendGeometry.hpp"
25 
26 namespace mimmo{
27 
28 
33  m_name = "mimmo.BendGeometry";
34  m_degree.fill({{0,0,0}});
35  m_origin.fill(0.0);
36  m_system = { 1.0 , 0.0 , 0.0 , 0.0, 1.0, 0.0 , 0.0 , 0.0 , 1.0 };
37  m_local = false;
38 };
39 
40 
45 BendGeometry::BendGeometry(const bitpit::Config::Section & rootXML){
46 
47  m_name = "mimmo.BendGeometry";
48  m_degree.fill({{0,0,0}});
49  m_origin.fill(0.0);
50  m_system = { 1.0 , 0.0 , 0.0 , 0.0, 1.0, 0.0 , 0.0 , 0.0 , 1.0 };
51  m_local = false;
52 
53  std::string fallback_name = "ClassNONE";
54  std::string input = rootXML.get("ClassName", fallback_name);
55  input = bitpit::utils::string::trim(input);
56  if(input == "mimmo.BendGeometry"){
57  absorbSectionXML(rootXML);
58  }else{
60  };
61 }
62 
67 
72  m_origin = other.m_origin;
73  m_system = other.m_system;
74  m_local = other.m_local;
75  m_filter = other.m_filter;
76  m_degree = other.m_degree;
77  m_coeffs = other.m_coeffs;
78 };
79 
84  swap(other);
85  return *this;
86 }
87 
92 void BendGeometry::swap(BendGeometry & x) noexcept
93 {
94  std::swap(m_origin, x.m_origin);
95  std::swap(m_system, x.m_system);
96  std::swap(m_local , x.m_local);
97  m_filter.swap(x.m_filter);
98  std::swap(m_degree, x.m_degree);
99  std::swap(m_coeffs, x.m_coeffs);
100  m_displ.swap(x.m_displ);
102 }
106 void
108  bool built = true;
109  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, BendGeometry>(&m_geometry, M_GEOM, true));
110  built = (built && createPortIn<dmpvector1D*, BendGeometry>(this, &mimmo::BendGeometry::setFilter, M_FILTER));
111  built = (built && createPortIn<umatrix33E, BendGeometry>(&m_degree, M_BMATRIX));
112  built = (built && createPortIn<dmat33Evec*, BendGeometry>(this, &BendGeometry::setCoeffs, M_BCOEFFS));
113  built = (built && createPortIn<dmatrix33E, BendGeometry>(&m_system, M_AXES));
114  built = (built && createPortIn<darray3E, BendGeometry>(&m_origin, M_POINT));
115  built = (built && createPortOut<dmpvecarr3E*, BendGeometry>(this, &mimmo::BendGeometry::getDisplacements, M_GDISPLS));
116  built = (built && createPortOut<MimmoSharedPointer<MimmoObject>, BendGeometry>(this, &BaseManipulation::getGeometry, M_GEOM));
117  m_arePortsBuilt = built;
118 };
119 
123 darray3E
125  return(m_origin);
126 }
127 
133  return(m_system);
134 }
135 
141  return(m_degree);
142 };
143 
149 dmat33Evec *
151  return &m_coeffs;
152 };
153 
159  return &m_displ;
160 };
161 
166 void
168  for(int i=0; i<3; ++i){
169  for(int j=0; j<3; ++j){
170  setDegree(i,j, degree[i][j]);
171  }
172  }
173 };
174 
181 void
182 BendGeometry::setDegree(int i, int j, uint32_t degree){
183  m_degree[i][j] = degree;
184  m_coeffs[i][j].resize(degree+1, 0.0);
185 };
186 
193 void
195  if(!coeffs) return;
196  m_coeffs = *coeffs;
197 };
198 
205 void
206 BendGeometry::setCoeffs(int i, int j, dvector1D coeffs){
207  m_coeffs[i][j] = coeffs;
208 };
209 
214 void
216  m_origin = origin;
217  m_local = true;
218 }
219 
224 void
226  m_system[0] = axes[0];
227  m_system[1] = axes[1];
228  m_system[2] = axes[2];
229  m_local = true;
230 }
231 
236 void
238  m_filter = *filter;
239 }
240 
246 void
248 
249  if(getGeometry() == nullptr){
250  (*m_log)<<m_name + " : nullptr pointer to linked geometry found"<<std::endl;
251  throw std::runtime_error(m_name + "nullptr pointer to linked geometry found");
252  }
253 
254  m_displ.clear();
256  m_displ.reserve(getGeometry()->getNVertices());
257  m_displ.setGeometry(getGeometry());
258 
259 
260  //check coherence of degrees and coeffs;
261  for(int i=0; i<3; ++i){
262  for(int j=0; j<3; ++j){
263  m_coeffs[i][j].resize(m_degree[i][j]+1, 0.0);
264  }
265  }
266 
267  checkFilter();
268 
269  long ID;
270  darray3E value;
271  darray3E point, point0;
272  for (const auto & vertex : m_geometry->getVertices()){
273  point = vertex.getCoords();
274  if (m_local){
275  point0 = point;
276  point = toLocalCoord(point);
277  }
278  ID = vertex.getId();
279  value.fill(0.0);
280  for (int j=0; j<3; j++){
281  for (int z=0; z<3; z++){
282  if (m_degree[j][z] > 0){
283  for (int k=0; k<(int)m_degree[j][z]+1; k++){
284  value[j] += pow(point[z],(double)k)*m_coeffs[j][z][k]*m_filter[ID];
285  }
286  }
287  }
288  }
289  if (m_local){
290  point += value;
291  point = toGlobalCoord(point);
292  value = point - point0;
293  }
294  m_displ.insert(ID, value);
295  }
296 };
297 
301 void
303  _apply(m_displ);
304 }
305 
310 void
312  bool check = m_filter.getDataLocation() == mimmo::MPVLocation::POINT;
313  check = check && m_filter.completeMissingData(0.0);
314  check = check && m_filter.getGeometry() == getGeometry();
315 
316  if (!check){
317  m_log->setPriority(bitpit::log::Verbosity::DEBUG);
318  (*m_log)<<"Not valid filter found in "<<m_name<<". Proceeding with default unitary field"<<std::endl;
319  m_log->setPriority(bitpit::log::Verbosity::NORMAL);
320 
321  m_filter.clear();
322  m_filter.setGeometry(m_geometry);
324  m_filter.reserve(getGeometry()->getNVertices());
325  for (const auto & vertex : getGeometry()->getVertices()){
326  m_filter.insert(vertex.getId(), 1.0);
327  }
328  }
329 }
330 
335 darray3E
336 BendGeometry::toLocalCoord(darray3E point){
337  darray3E work;
338  //unapply origin translation
339  work = point - m_origin;
340  //apply change to local sdr transformation
341  return matmul(m_system, work);
342 };
343 
350 darray3E BendGeometry::toGlobalCoord(darray3E point){
351 
352  darray3E work, work2;
353  //unscale your local point
354  for(int i =0; i<3; ++i){
355  work[i] = point[i];
356  }
357 
358  //unapply change to local sdr transformation
359  work2 = matmul(work, m_system);
360 
361  //unapply origin translation
362  return (work2 + m_origin);
363 };
364 
372 
373  darray3E out;
374  for (std::size_t i = 0; i < 3; i++) {
375  out[i] = 0.0;
376  for (std::size_t j = 0; j <3; j++) {
377  out[i] += vec[j]*mat[j][i];
378  } //next j
379  } //next i
380 
381  return out;
382 }
383 
391 
392  darray3E out;
393  for (std::size_t i = 0; i < 3; i++) {
394  out[i] = 0.0;
395  for (std::size_t j = 0; j <3; j++) {
396  out[i] += vec[j]*mat[i][j];
397  } //next j
398  } //next i
399 
400  return out;
401 }
402 
408 void
409 BendGeometry::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
410 
411  BITPIT_UNUSED(name);
412 
413  std::string input;
414 
415  BaseManipulation::absorbSectionXML(slotXML, name);
416 
417  if(slotXML.hasSection("DegreesMatrix")){
418  auto & subslot = slotXML.getSection("DegreesMatrix");
419  umatrix33E temp;
420  temp.fill({{0,0,0}});
421 
422  if(subslot.hasOption("xDispl")){
423  input = subslot.get("xDispl");
424  std::stringstream ss(bitpit::utils::string::trim(input));
425  for(int i=0; i<3; ++i) ss>>temp[0][i];
426  }
427 
428  if(subslot.hasOption("yDispl")){
429  input = subslot.get("yDispl");
430  std::stringstream ss(bitpit::utils::string::trim(input));
431  for(int i=0; i<3; ++i) ss>>temp[1][i];
432  }
433 
434  if(subslot.hasOption("zDispl")){
435  input = subslot.get("zDispl");
436  std::stringstream ss(bitpit::utils::string::trim(input));
437  for(int i=0; i<3; ++i) ss>>temp[2][i];
438  }
439 
440  setDegree(temp);
441  };
442 
443  // set Degree already set correctly the matrix of coeffs..
444  if(slotXML.hasSection("PolyCoefficients")){
445  auto & subslot = slotXML.getSection("PolyCoefficients");
446  dmat33Evec &temp = m_coeffs;
447  std::string rootPoly = "Poly";
448  std::string locPoly;
449  int ik,jk;
450  for (int k=0; k<9; ++k){
451  locPoly = rootPoly + std::to_string(k);
452  if(subslot.hasOption(locPoly)){
453  input = subslot.get(locPoly);
454  std::stringstream ss(bitpit::utils::string::trim(input));
455  ik = (int)(k/3);
456  jk = k%3;
457  for(double & val: temp[ik][jk]) ss>>val;
458  }
459  }
460  };
461 
462  if(slotXML.hasOption("Origin")){
463  std::string input = slotXML.get("Origin");
464  input = bitpit::utils::string::trim(input);
465  darray3E temp = {{0.0,0.0,0.0}};
466  if(!input.empty()){
467  std::stringstream ss(input);
468  for(auto &val : temp) ss>>val;
469  }
470  setOrigin(temp);
471  };
472 
473  if(slotXML.hasSection("RefSystem")){
474  const bitpit::Config::Section & rfXML = slotXML.getSection("RefSystem");
475  std::string rootAxis = "axis";
476  std::string axis;
477  dmatrix33E temp;
478  temp[0].fill(0.0); temp[0][0] = 1.0;
479  temp[1].fill(0.0); temp[1][1] = 1.0;
480  temp[2].fill(0.0); temp[2][2] = 1.0;
481  for(int i=0; i<3; ++i){
482  axis = rootAxis + std::to_string(i);
483  std::string input = rfXML.get(axis);
484  input = bitpit::utils::string::trim(input);
485  if(!input.empty()){
486  std::stringstream ss(input);
487  for(auto &val : temp[i]) ss>>val;
488  }
489  }
490  setRefSystem(temp);
491  };
492 };
493 
499 void
500 BendGeometry::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
501 
502  BITPIT_UNUSED(name);
503 
504  BaseManipulation::flushSectionXML(slotXML, name);
505 
506  bitpit::Config::Section & degXML = slotXML.addSection("DegreesMatrix");
507 
508  svector1D d_str(3);
509  int counter = 0;
510  for(auto & val: m_degree){
511  std::stringstream ss;
512  for(auto & loc: val) ss<<loc<<'\t';
513  d_str[counter] = ss.str();
514  ++counter;
515  }
516 
517  degXML.set("xDispl", d_str[0]);
518  degXML.set("yDispl", d_str[1]);
519  degXML.set("zDispl", d_str[2]);
520 
521  bitpit::Config::Section & polyXML = slotXML.addSection("PolyCoefficients");
522  std::string rootPoly = "Poly";
523  std::string locPoly;
524  for(int i=0; i<3; i++){
525  for(int j =0; j<3; j++){
526  if(m_coeffs[i][j].empty()) continue;
527  locPoly = rootPoly + std::to_string(int(i*3+j));
528  std::stringstream ss;
529  for(auto & loc: m_coeffs[i][j]) ss<<loc<<'\t';
530  polyXML.set(locPoly, ss.str());
531  }
532  }
533 
534  {
535  std::stringstream ss;
536  ss<<std::scientific<<getOrigin()[0]<<'\t'<<getOrigin()[1]<<'\t'<<getOrigin()[2];
537  slotXML.set("Origin", ss.str());
538  }
539 
540  {
541  auto rs = getRefSystem();
542  bitpit::Config::Section & rsXML = slotXML.addSection("RefSystem");
543  std::string rootAxis = "axis";
544  std::string localAxis;
545  int counter=0;
546  for(auto &axis : rs){
547  localAxis = rootAxis+std::to_string(counter);
548  std::stringstream ss;
549  ss<<std::scientific<<axis[0]<<'\t'<<axis[1]<<'\t'<<axis[2];
550  rsXML.set(localAxis, ss.str());
551  ++counter;
552  }
553  }
554 
555 };
556 
557 }
#define M_GDISPLS
std::array< darr3Evec, 3 > dmat33Evec
#define M_GEOM
std::vector< std::string > svector1D
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
void swap(BendGeometry &x) noexcept
void setDegree(umatrix33E degree)
BendGeometry & operator=(BendGeometry other)
umatrix33E getDegree()
bool completeMissingData(const mpv_t &defValue)
#define M_POINT
void warningXML(bitpit::Logger *log, std::string name)
BendGeometry applies custom bending deformations along axis-directions of a target geometry.
dmpvecarr3E * getDisplacements()
BaseManipulation is the base class of any manipulation object of the library.
MimmoSharedPointer< MimmoObject > getGeometry() const
#define M_BCOEFFS
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
dmat33Evec * getCoeffs()
std::array< darray3E, 3 > dmatrix33E
std::vector< double > dvector1D
#define M_BMATRIX
#define M_AXES
MimmoSharedPointer< MimmoObject > m_geometry
static darray3E matmul(const darray3E &vec, const dmatrix33E &mat)
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
std::array< uarray3E, 3 > umatrix33E
void _apply(MimmoPiercedVector< darray3E > &displacements)
void setOrigin(darray3E origin)
void setDataLocation(MPVLocation loc)
std::array< double, 3 > darray3E
void setFilter(dmpvector1D *filter)
void setCoeffs(dmat33Evec *coeffs)
MimmoSharedPointer< MimmoObject > getGeometry()
dmatrix33E getRefSystem()
void swap(BaseManipulation &x) noexcept
void setRefSystem(dmatrix33E axes)
#define M_FILTER