FFDLattice.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 "FFDLattice.hpp"
26 
27 namespace mimmo{
28 
31  m_knots.resize(3);
32  m_mapEff.resize(3);
33  m_deg.fill(1);
34  m_mapNodes.resize(3);
35  m_globalDispl = false;
36  m_bfilter = false;
37  m_name = "mimmo.FFDlattice";
38 };
39 
44 FFDLattice::FFDLattice(const bitpit::Config::Section & rootXML){
45 
46  m_knots.resize(3);
47  m_mapEff.resize(3);
48  m_deg.fill(1);
49  m_mapNodes.resize(3);
50  m_globalDispl = false;
51  m_bfilter = false;
52  m_name = "mimmo.FFDlattice";
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.FFDLattice"){
58  absorbSectionXML(rootXML);
59  }else{
61  };
62 }
63 
66 
71  m_deg = other.m_deg;
72  m_knots = other.m_knots;
73  m_mapEff = other.m_mapEff;
74  m_weights = other.m_weights;
75  m_displ = other.m_displ;
76  m_mapNodes = other.m_mapNodes;
77  m_mapdeg = other.m_mapdeg;
78  m_globalDispl = other.m_globalDispl;
79  m_bfilter = other.m_bfilter;
80  m_filter = other.m_filter;
81  m_collect_wg = other.m_collect_wg;
82 };
83 
84 
89  swap(other);
90  return *this;
91 }
92 
97 void FFDLattice::swap(FFDLattice & x) noexcept
98 {
99  std::swap(m_deg, x.m_deg);
100  std::swap(m_knots, x.m_knots);
101  std::swap(m_mapEff, x.m_mapEff);
102  std::swap(m_weights, x.m_weights);
103  std::swap(m_displ, x.m_displ);
104  std::swap(m_mapNodes, x.m_mapNodes);
105  std::swap(m_mapdeg, x.m_mapdeg);
106  std::swap(m_globalDispl, x.m_globalDispl);
107  std::swap(m_bfilter, x.m_bfilter);
108  m_filter.swap(x.m_filter);
109  std::swap(m_collect_wg, x.m_collect_wg);
110  m_gdispl.swap(x.m_gdispl);
111  Lattice::swap(x);
112 }
113 
116 void
118 
120 
121  bool built = true;
122 
123  //input
124  built = (built && createPortIn<dvecarr3E, FFDLattice>(this, &mimmo::FFDLattice::setDisplacements, M_DISPLS));
125  built = (built && createPortIn<dmpvector1D*, FFDLattice>(this, &mimmo::FFDLattice::setFilter,M_FILTER));
126  built = (built && createPortIn<iarray3E, FFDLattice>(this, &mimmo::FFDLattice::setDegrees, M_DEG));
127  built = (built && createPortIn<dvector1D, FFDLattice>(this, &mimmo::FFDLattice::setNodalWeight, M_NURBSWEIGHTS));
128  built = (built && createPortIn<std::array<mimmo::CoordType,3>, FFDLattice>(this, &mimmo::FFDLattice::setCoordType, M_NURBSCOORDTYPE));
129 
130  //output
131  built = (built && createPortOut<dmpvecarr3E*, FFDLattice>(this, &mimmo::FFDLattice::getDeformation, M_GDISPLS));
132  built = (built && createPortOut<iarray3E, FFDLattice>(this, &mimmo::FFDLattice::getDegrees, M_DEG));
133  built = (built && createPortOut<dmpvector1D*, FFDLattice>(this, &mimmo::FFDLattice::getFilter, M_FILTER));
134  built = (built && createPortOut<dvector1D, FFDLattice>(this, &mimmo::FFDLattice::getWeights,M_NURBSWEIGHTS));
135  built = (built && createPortOut<std::array<mimmo::CoordType,3>, FFDLattice>(this, &mimmo::FFDLattice::getCoordType, M_NURBSCOORDTYPE));
136  m_arePortsBuilt = built;
137 };
138 
140 void
143  clearKnots(); //clear all knots stuff;
144  clearFilter();
145  m_displ.clear();
146 
147 };
148 
150 void
152  m_filter.clear();
153  m_bfilter = false;
154 };
155 
156 
163 ivector1D
165  ivector1D res(6,0);
166 
167  //effectively stored
168  res[0] = m_knots[0].size();
169  res[1] = m_knots[1].size();
170  res[2] = m_knots[2].size();
171 
172  //theoretical stored
173  res[3] = m_mapEff[0].size();
174  res[4] = m_mapEff[1].size();
175  res[5] = m_mapEff[2].size();
176  return(res);
177 };
178 
183 dvector1D
185  return(recoverFullNodeWeights());
186 };
187 
193 void
195  knots.resize(3);
196  mapTheo.resize(3);
197 
198  returnKnotsStructure(0, knots[0], mapTheo[0]);
199  returnKnotsStructure(1, knots[1], mapTheo[1]);
200  returnKnotsStructure(2, knots[2], mapTheo[2]);
201 };
202 
209 void
211  if(dir<0 || dir>2){return;}
212 
213  knots.resize(m_knots[dir].size());
214  mapT.resize(m_mapEff[dir].size());
215 
216  knots = m_knots[dir];
217  mapT = m_mapEff[dir];
218 };
219 
223 iarray3E
225  iarray3E deg;
226  deg[0] = m_deg[0];
227  deg[1] = m_deg[1];
228  deg[2] = m_deg[2];
229  return(deg);
230 }
231 
235 dvecarr3E*
237  if(m_displ.empty()) return nullptr;
238  return(&m_displ);
239 };
240 
246  return &m_filter;
247 };
248 
253 dmpvecarr3E *
255  return &m_gdispl;
256 };
257 
258 
263 bool
264 FFDLattice::isDisplGlobal(){return(m_globalDispl);}
265 
266 
272 void
274  m_deg = degrees;
275  m_isBuild = false;
276 };
277 
278 
283 void
285  m_displ = displacements;
286 };
287 
297 void
298 FFDLattice::setDisplGlobal(bool flag){m_globalDispl = flag;}
299 
300 
315 void
316 FFDLattice::setLattice(darray3E &origin,darray3E & span, ShapeType type, iarray3E & dimensions, iarray3E & degrees){
317 
318  if(m_shape){m_shape.reset(nullptr);}
319 
320  setShape(type);
321  setOrigin(origin);
322  setSpan(span);
323  setDimension(dimensions);
324  setDegrees(degrees);
325  build();
326 };
327 
341 void
342 FFDLattice::setLattice(darray3E &origin,darray3E & span, ShapeType type, dvector1D & spacing, iarray3E & degrees ){
343 
344  ivector1D dimLimit(3,2);
345  //create internal shape using unique_ptr member.
346  if(m_shape){m_shape.reset(nullptr);}
347 
348  switch(type){
349  case ShapeType::CYLINDER :
350  dimLimit[1] = 4;
351  break;
352  case ShapeType::SPHERE :
353  dimLimit[1] = 5; dimLimit[2] = 3;
354  break;
355  default://CUBE //WEDGE
356  break;
357  }
358 
359  setShape(type);
360  setOrigin(origin);
361  setSpan(span);
362 
363  darray3E span2 = getSpan();
364  iarray3E dim;
365 
366  for(int i=0; i<3; ++i){
367  if(spacing[i] != 0.0) {
368  dim[i] = (int) std::floor(span2[i]/spacing[i] +0.5) + 1;
369  }else{
370  dim[i] = dimLimit[i];
371  }
372  }
373 
374  setDimension(dim);
375  setDegrees(degrees);
376  build();
377 };
378 
390 void
391 FFDLattice::setLattice(BasicShape * shape, iarray3E & dimensions, iarray3E & degrees){
392 
393  setShape(shape);
394  setDimension(dimensions);
395  setDegrees(degrees);
396  build();
397 
398 };
399 
411 void
412 FFDLattice::setLattice(BasicShape * shape, dvector1D & spacing, iarray3E & degrees){
413 
414  ivector1D dimLimit(3,2);
415  //create internal shape using unique_ptr member.
416  if(m_shape){m_shape.reset(nullptr);}
417 
418  switch(shape->getShapeType()){
419  case ShapeType::CYLINDER :
420  dimLimit[1] = 4;
421  break;
422  case ShapeType::SPHERE :
423  dimLimit[1] = 5; dimLimit[2] = 3;
424  break;
425  default://CUBE //WEDGE
426  break;
427  }
428 
429  setShape(shape);
430 
431  darray3E span2 = getSpan();
432  iarray3E dim;
433 
434  for(int i=0; i<3; ++i){
435  if(spacing[i] != 0.0) {
436  dim[i] = (int) std::floor(span2[i]/spacing[i] +0.5) + 1;
437  }else{
438  dim[i] = dimLimit[i];
439  }
440  }
441 
442  setDimension(dim);
443  setDegrees(degrees);
444  build();
445 
446 };
447 
452 void
453 FFDLattice::setNodalWeight(double val, int index){
454  int ind = accessDOFFromGrid(index);
455  m_collect_wg[ind] = val;
456  m_isBuild = false;
457 };
458 
465 void
466 FFDLattice::setNodalWeight(double val, int i, int j, int k){
467  int index = accessPointIndex(i,j,k);
468  setNodalWeight(val, index);
469 };
470 
474 void
476  int counter = 0;
477  for(auto & val : wg){
478  setNodalWeight(val, counter);
479  counter++;
480  }
481 
482 };
483 
488 void
490  if(!filter) return;
491  m_filter.clear();
492  m_bfilter = !(filter->empty());
493  m_filter = *filter;
494 };
495 
505 void
506 FFDLattice::plotGrid(std::string directory, std::string filename,int counter, bool binary, bool deformed){
507 
508  iarray3E n = getDimension();
509  int size = n[0]*n[1]*n[2];
510  ivector1D labels(size);
511  for(int i=0; i<size; ++i){
512  labels[i] = accessDOFFromGrid(i);
513  }
514 
515  if(deformed){
516  dvecarr3E dispXYZ;
517  if(isDisplGlobal()){
518  dispXYZ = recoverFullGridDispl();
519  }else{
520  dispXYZ = convertDisplToXYZ();
521  }
522  dvecarr3E data(size);
523  for(int i=0; i<size; ++i){
524  data[i] = getGlobalPoint(i) + dispXYZ[i];
525  }
526  UStructMesh::plotGrid(directory, filename, counter, binary, labels, &data);
527  }else{
528  dvecarr3E* pnull = nullptr;
529  UStructMesh::plotGrid(directory, filename, counter, binary, labels, pnull);
530 
531  }
532 
533 
534 };
535 
545 void
546 FFDLattice::plotCloud(std::string directory, std::string filename, int counter, bool binary, bool deformed){
547 
548  iarray3E n = getDimension();
549  int size = n[0]*n[1]*n[2];
550  ivector1D labels(size);
551  for(int i=0; i<size; ++i){
552  labels[i] = accessDOFFromGrid(i);
553  }
554 
555  if(deformed){
556  dvecarr3E dispXYZ;
557  if(isDisplGlobal()){
558  dispXYZ = recoverFullGridDispl();
559  }else{
560  dispXYZ = convertDisplToXYZ();
561  }
562  dvecarr3E data(size);
563  for(int i=0; i<size; ++i){
564  data[i] = getGlobalPoint(i) + dispXYZ[i];
565  }
566  UStructMesh::plotCloud(directory, filename, counter, binary, labels, &data);
567  }else{
568  dvecarr3E* pnull = nullptr;
569  UStructMesh::plotCloud(directory, filename, counter, binary, labels, pnull);
570 
571  }
572 
573 };
574 
579 void
581 
583  if(container == nullptr){
584  (*m_log)<<m_name + " : nullptr pointer to linked geometry found"<<std::endl;
585  throw std::runtime_error(m_name + "nullptr pointer to linked geometry found");
586  }
587 
588  //reset displacement in a unique vector
589  m_gdispl.clear();
591  m_gdispl.reserve(getGeometry()->getNVertices());
593 
594  //build trees
595  if(container->isSkdTreeSupported() && container->getSkdTreeSyncStatus() != SyncStatus::SYNC){
596  container->buildSkdTree();
597  }
598  else if(container->getKdTreeSyncStatus() != SyncStatus::SYNC){
599  container->buildKdTree();
600  }
601 
602  if(!isBuilt()){
603  build();
604  }
605 
606  livector1D map;
607  dvecarr3E localdef = apply(map);
608 
609  long int ID;
610  darray3E zero;
611  zero.fill(0.0);
612  for (const auto & vertex : container->getVertices()){
613  ID = vertex.getId();
614  m_gdispl.insert(ID, zero);
615  }
616  {
617  int counter = 0;
618  for(const auto &mapp: map){
619  m_gdispl[mapp] = localdef[counter];
620  ++counter;
621  }
622  }
623 
624 };
625 
633 darray3E
635  darray3E result;
636  result.fill(0.0);
637  if(!getShape()->isPointIncluded(point) || !isBuilt()) return result;
638  return(nurbsEvaluator(point));
639 };
640 
649 dvecarr3E
651 
653  list.clear();
654  if(container == nullptr) return dvecarr3E(0);
655  if(!isBuilt()) return dvecarr3E(0);
656 
657 
658  //check simplex included and extract their vertex in global IDs;
659  if(container->isSkdTreeSupported()) list= container->getVertexFromCellList(getShape()->includeGeometry(container));
660  else list= getShape()->includeCloudPoints(container);
661  //return deformation
662  dvecarr3E result = nurbsEvaluator(list);
663  if(m_bfilter){
664 
665  checkFilter();
666 
667  dvecarr3E::iterator itL= result.begin();
668  for ( auto && vID : list){
669  *itL = (*itL) * m_filter[vID];
670  ++itL;
671  }
672  }
673  return(result);
674 };
675 
684 dvecarr3E
686 
687  dvecarr3E result;
688  if(point ==nullptr || !isBuilt() ) return result;
689 
690  result.resize(point->size(), darray3E{{0,0,0}});
691  livector1D list = getShape()->includeCloudPoints(*point);
692 
693  for(const auto & index : list){
694  darray3E target = (*point)[index];
695  result[index] = nurbsEvaluator(target);
696  }
697 
698  return(result);
699 };
700 
704 void
705 FFDLattice::apply(){
706  _apply(m_gdispl);
707 }
708 
713 void
714 FFDLattice::checkFilter(){
715  bool check = m_filter.getDataLocation() == mimmo::MPVLocation::POINT;
716  check = check && m_filter.completeMissingData(0.0);
717  check = check && m_filter.getGeometry() == getGeometry();
718 
719  if (!check){
720  m_log->setPriority(bitpit::log::Verbosity::DEBUG);
721  (*m_log)<<"Not valid filter found in "<<m_name<<". Proceeding with default unitary field"<<std::endl;
722  m_log->setPriority(bitpit::log::Verbosity::NORMAL);
723 
724  m_filter.clear();
725  m_filter.setGeometry(m_geometry);
726  m_filter.setDataLocation(mimmo::MPVLocation::POINT);
727  m_filter.reserve(getGeometry()->getNVertices());
728  for (const auto & vertex : getGeometry()->getVertices()){
729  m_filter.insert(vertex.getId(), 1.0);
730  }
731  }
732 }
733 
739 darray3E
740 FFDLattice::convertDisplToXYZ(darray3E & target, int i){
741 
742  darray3E scaling = getScaling();
743  darray3E work;
744  for(int i=0; i<3; ++i){
745  work[i] = target[i]/scaling[i];
746  }
747  work += getLocalPoint(i);
748  darray3E result = transfToGlobal(work) - getGlobalPoint(i);
749  return(result);
750 };
751 
755 dvecarr3E
756 FFDLattice::convertDisplToXYZ(){
757 
758  dvecarr3E displ = recoverFullGridDispl();
759  int sizeD = displ.size();
760 
761  dvecarr3E result(sizeD);
762  for(int i=0; i<sizeD; ++i){
763  result[i] = convertDisplToXYZ(displ[i],i);
764  }
765  return(result);
766 };
767 
772 darray3E
773 FFDLattice::nurbsEvaluator(darray3E & pointOr){
774 
775  darray3E point = transfToLocal(pointOr);
776  darray3E scaling = getShape()->getScaling();
777 
778  ivector1D knotInterval(3,0);
779  dvector2D BSbasis(3);
780  dvector1D valH(4,0), temp1(4,0),temp2(4,0), zeros(4,0);
781  int uind, vind, wind, index;
782 
783  dvecarr3E* displ = getDisplacements();
784 
785  int i0 = m_mapdeg[0];
786  int i1 = m_mapdeg[1];
787  int i2 = m_mapdeg[2];
788 
789  iarray3E mappedIndex;
790 
791  for(int i=0; i<3; i++){
792  knotInterval[i] = getKnotInterval(point[i],i);
793  BSbasis[i] = basisITS0(knotInterval[i], i, point[i]);
794  }
795 
796  uind = knotInterval[i0] - m_deg[i0];
797  vind = knotInterval[i1] - m_deg[i1];
798  wind = knotInterval[i2] - m_deg[i2];
799 
800  for(int i=0; i<=m_deg[i0]; ++i){
801 
802  mappedIndex[0] = uind+i;
803  temp1 = zeros;
804 
805  for(int j=0; j<=m_deg[i1]; ++j){
806 
807  mappedIndex[1] = vind+j;
808  temp2 = zeros;
809 
810  for(int k=0; k<=m_deg[i2]; ++k){
811 
812  mappedIndex[2] = wind+k;
813  index = accessMapNodes(mappedIndex[0],mappedIndex[1],mappedIndex[2]);
814 
815  for(int intv=0; intv<3; ++intv){
816  temp2[intv] += BSbasis[i2][k]*m_weights[m_intMapDOF[index]]*(*displ)[m_intMapDOF[index]][intv];
817  }
818  temp2[3] += BSbasis[i2][k]*m_weights[index];
819  }
820  for(int intv=0; intv<4; ++intv){
821  temp1[intv] += BSbasis[i1][j]*temp2[intv];
822  }
823 
824  }
825  for(int intv=0; intv<4; ++intv){
826  valH[intv] += BSbasis[i0][i]*temp1[intv];
827  }
828  }
829 
830  darray3E outres;
831  if(isDisplGlobal()){
832  for(int i=0; i<3; ++i){
833  outres[i] = valH[i]/valH[3];
834  }
835 
836  }else{
837  //summing scaled displ in local ref frame;
838  for(int i=0; i<3; ++i){
839  point[i] += valH[i]/(valH[3]*scaling[i]);
840  }
841 
842  //get final displ in global ref frame:
843  outres = transfToGlobal(point) - pointOr;
844  }
845  return(outres);
846 
847 };
848 
855 dvecarr3E
856 FFDLattice::nurbsEvaluator(livector1D & list){
857 
858  bitpit::PatchKernel * tri = getGeometry()->getPatch();
859  long int id;
860  int lsize = list.size();
861  livector1D::iterator it, itend = list.end();
862  darray3E target, point;
863  ivector1D knotInterval(3,0);
864  dvector1D BSbasisi0, BSbasisi1, BSbasisi2;
865  dvector1D valH(4,0), temp1(4,0),temp2(4,0);
866 
867  dvecarr3E displ = recoverFullGridDispl();
868  dvector1D weig = recoverFullNodeWeights();
869 
870  int uind, vind, wind, index;
871 
872  int intv, i, j, k;
873 
874  int i0 = m_mapdeg[0];
875  int i1 = m_mapdeg[1];
876  int i2 = m_mapdeg[2];
877  iarray3E mappedIndex;
878 
879  int md0 = m_deg[i0];
880  int md1 = m_deg[i1];
881  int md2 = m_deg[i2];
882 
883  dvecarr3E outres(lsize);
884  dvecarr3E::iterator itout = outres.begin();
885  darray3E scaling = getShape()->getScaling();
886 
887  double bbasisw2;
888  double bbasis1, bbasis0;
889 
890  for(it = list.begin(); it != itend; ++it){
891 
892  for(intv=0; intv<4; ++intv){
893  valH[intv] = 0.0;
894  }
895  id = *it;
896  target = tri->getVertex(id).getCoords();
897  point = transfToLocal(target);
898 
899  // get reference Interval int the knot matrix
900  for(i=0; i<3; i++){
901  knotInterval[i] = getKnotInterval(point[i],i);
902  }
903  BSbasisi0 = basisITS0(knotInterval[i0], i0, point[i0]);
904  BSbasisi1 = basisITS0(knotInterval[i1], i1, point[i1]);
905  BSbasisi2 = basisITS0(knotInterval[i2], i2, point[i2]);
906 
907  uind = knotInterval[i0] - md0;
908  vind = knotInterval[i1] - md1;
909  wind = knotInterval[i2] - md2;
910 
911 
912  for(i=0; i<=md0; ++i){
913 
914  mappedIndex[i0] = uind + i;
915 
916  for(int intv=0; intv<4; ++intv){
917  temp1[intv] = 0.0;
918  }
919 
920  for(j=0; j<=md1; ++j){
921 
922  mappedIndex[i1] = vind + j;
923 
924  for(intv=0; intv<4; ++intv){
925  temp2[intv] = 0.0;
926  }
927 
928  for(k=0; k<=md2; ++k){
929 
930  mappedIndex[i2] = wind + k;
931 
932  index = accessMapNodes(mappedIndex[0], mappedIndex[1], mappedIndex[2]);
933 
934  bbasisw2 = BSbasisi2[k]* weig[index];
935 
936  for(intv=0; intv<3; ++intv){
937  temp2[intv] += bbasisw2 * displ[index][intv];
938  }
939  temp2[3] += bbasisw2;
940 
941  }
942  bbasis1 = BSbasisi1[j];
943  for(intv=0; intv<4; ++intv){
944  temp1[intv] += bbasis1*temp2[intv];
945  }
946 
947  }
948  bbasis0 = BSbasisi0[i];
949  for(intv=0; intv<4; ++intv){
950  valH[intv] += bbasis0*temp1[intv];
951  }
952  }
953 
954 
955  if(isDisplGlobal()){
956 
957  //adding to local point displ rescaled
958  for(i=0; i<3; ++i){
959  (*itout)[i] = valH[i]/valH[3];
960  }
961 
962  }else{
963 
964  //adding to local point displ rescaled
965  for(i=0; i<3; ++i){
966  point[i]+= valH[i]/(valH[3]*scaling[i]);
967  }
968 
969  //get absolute displ as difference of
970  for(i=0; i<3; ++i){
971  (*itout)[i] = transfToGlobal(point)[i] - target[i];
972  }
973 
974  }
975 
976  itout++;
977 
978  }//next list id
979 
980  itout = outres.end();
981 
982  return(outres);
983 
984 };
985 
991 double
992 FFDLattice::nurbsEvaluatorScalar(darray3E & coordOr, int targ){
993 
994  darray3E point = transfToLocal(coordOr);
995  double scaling = getScaling()[targ];
996 
997  ivector1D knotInterval(3,0);
998  dvector2D BSbasis(3);
999  dvector1D valH(2,0), temp1(2,0),temp2(2,0), zeros(2,0);
1000  int uind, vind, wind, index;
1001 
1002  dvecarr3E* displ = getDisplacements();
1003 
1004  int i0 = m_mapdeg[0];
1005  int i1 = m_mapdeg[1];
1006  int i2 = m_mapdeg[2];
1007 
1008  int md0 = m_deg[i0];
1009  int md1 = m_deg[i1];
1010  int md2 = m_deg[i2];
1011 
1012  iarray3E mappedIndex;
1013 
1014  for(int i=0; i<3; i++){
1015  knotInterval[i] = getKnotInterval(point[i],i);
1016  BSbasis[i] = basisITS0(knotInterval[i], i, point[i]);
1017  }
1018 
1019  uind = knotInterval[i0] - md0;
1020  vind = knotInterval[i1] - md1;
1021  wind = knotInterval[i2] - md2;
1022 
1023  for(int i=0; i<=md0; ++i){
1024 
1025  mappedIndex[0] = uind+i;
1026  temp1 = zeros;
1027 
1028  for(int j=0; j<=md1; ++j){
1029 
1030  mappedIndex[1] = vind+j;
1031  temp2 = zeros;
1032 
1033  for(int k=0; k<=md2; ++k){
1034 
1035  mappedIndex[2] = wind+k;
1036  index = accessMapNodes(mappedIndex[0],mappedIndex[1],mappedIndex[2]);
1037  temp2[0] += BSbasis[i2][k]*m_weights[m_intMapDOF[index]]*(*displ)[m_intMapDOF[index]][targ];
1038  temp2[1] += BSbasis[i2][k]*m_weights[index];
1039  }
1040 
1041  for(int intv=0; intv<2; ++intv){
1042  temp1[intv] += BSbasis[i1][j]*temp2[intv];
1043  }
1044 
1045  }
1046 
1047  for(int intv=0; intv<2; ++intv){
1048  valH[intv] += BSbasis[i0][i]*temp1[intv];
1049  }
1050  }
1051 
1052  darray3E res;
1053  if(isDisplGlobal()){
1054  res[targ] = valH[0]/valH[1];
1055  }else{
1056  point[targ] += valH[0]/(valH[1]*scaling);
1057  res = transfToGlobal(point)- coordOr;
1058  }
1059  return(res[targ]);
1060 };
1061 
1069 dvector1D
1070 FFDLattice::basisITS0(int k, int pos, double coord){
1071 
1072  //return local basis function given the local interval in theoretical knot index,
1073  //local degree of the curve -> Please refer to NURBS book of PEIGL for this Inverted Triangular Scheme Algorithm (pag 74);
1074  int dd1 = m_deg[pos]+1;
1075  dvector1D basis(dd1,1);
1076  dvector1D left(dd1,0), right(dd1,0);
1077  double saved, tmp;
1078 
1079  for(int j = 1; j < dd1; ++j){
1080  saved = 0.0;
1081  left[j] = coord - getKnotValue(k+1-j, pos);
1082  right[j]= getKnotValue(k+j, pos) - coord;
1083 
1084  for(int r = 0; r < j; ++r){
1085  tmp = basis[r]/(right[r+1] + left[j-r]);
1086  basis[r] = saved + right[r+1] * tmp;
1087  saved = left[j-r] * tmp;
1088  }//next r
1089 
1090  basis[j] = saved;
1091  }//next j
1092 
1093  return(basis);
1094 };
1095 
1100 dvector1D
1101 FFDLattice::getNodeSpacing(int dir){
1102 
1103  dvector1D result;
1104  int dim = getDimension()[dir];
1105  double span = getLocalSpan()[dir];
1106  double locOr= getShape()->getLocalOrigin()[dir];
1107 
1108  int nn, retroOrigin;
1109  double dKn, origin;
1110 
1111  switch(getCoordType(dir))
1112  {
1113  case CoordType::PERIODIC :
1114  nn = dim+m_deg[dir]-1;
1115  result.resize(nn);
1116  dKn = span/(dim-1);
1117 
1118  retroOrigin = (m_deg[dir]-1)/2 + (m_deg[dir]-1)%2;
1119  origin = locOr-1.0 * retroOrigin * dKn;
1120 
1121  for(int i=0; i<nn; ++i){
1122  result[i] = origin + i*dKn;
1123  }
1124  break;
1125 
1126  case CoordType::SYMMETRIC :
1127  nn = dim+m_deg[dir]-1;
1128  result.resize(nn);
1129  dKn = span/(dim-1);
1130 
1131  retroOrigin = (m_deg[dir]-1)/2 + (m_deg[dir]-1)%2;
1132  origin = locOr-1.0 * retroOrigin * dKn;
1133 
1134  for(int i=0; i<nn; ++i){
1135  result[i] = origin + i*dKn;
1136  }
1137  break;
1138 
1139  case CoordType::CLAMPED :
1140  nn = dim;
1141  result.resize(nn);
1142  dKn = span/(dim-1);
1143  for(int i=0; i<nn; ++i){
1144  result[i] =locOr+ i*dKn;
1145  }
1146  break;
1147 
1148  case CoordType::UNCLAMPED :
1149  nn = dim;
1150  result.resize(nn);
1151  dKn = span/(dim-1);
1152  for(int i=0; i<nn; ++i){
1153  result[i] =locOr+ i*dKn;
1154  }
1155  break;
1156 
1157  default: //never been reached
1158  break;
1159  }
1160 
1161  return(result);
1162 };
1163 
1165 void
1166 FFDLattice::clearKnots(){
1167 
1168  m_knots.clear();
1169  m_mapEff.clear();
1170  m_weights.clear();
1171  m_mapNodes.clear();
1172  m_collect_wg.clear();
1173 
1174  m_knots.resize(3);
1175  m_mapEff.resize(3);
1176  m_deg.fill(1.0);
1177  m_mapNodes.resize(3);
1178  m_mapdeg[0]=0; m_mapdeg[1]=1; m_mapdeg[2]=2;
1179 
1180 };
1181 
1183 void
1184 FFDLattice::setKnotsStructure(){
1185  for(int i=0; i<3; i++){
1186  setKnotsStructure(i,getCoordType(i));
1187  }
1188 }
1189 
1195 void
1196 FFDLattice::setKnotsStructure(int dir,CoordType type){
1197 
1198  //recover number of node for direction dir;
1199  iarray3E dim = getDimension();
1200  int nn = dim[dir];
1201 
1202  // free necessary knot structures
1203  m_knots[dir].clear();
1204  m_mapEff[dir].clear();
1205 
1206  dvector1D equinode = getNodeSpacing(dir);
1207  int nEff, kEff,kTheo, kend;
1208  double tol = 1.0E-12;
1209 
1210  switch(type){
1211  //clamped curve structure
1212  case CoordType::CLAMPED :
1213 
1214  m_deg[dir] = std::min(m_deg[dir], nn-1);
1215  kEff = nn - m_deg[dir] + 1;
1216  kTheo = nn + m_deg[dir] + 1;
1217  m_knots[dir].resize(kEff);
1218  m_mapEff[dir].resize(kTheo,0);
1219 
1220  //set knots grid in the dir space considered 1 for this example
1221  m_knots[dir][0] = equinode[0];
1222  m_knots[dir][kEff-1] = equinode[equinode.size()-1];
1223 
1224  for(int i=1; i<kEff-1; ++i){
1225  m_knots[dir][i] = 0.0;
1226  for(int j=i; j<=i+m_deg[dir]-1; ++j){
1227  m_knots[dir][i] += equinode[j]/((double) m_deg[dir]);
1228  }
1229  }
1230 
1231  for(int i=m_deg[dir]; i<(m_deg[dir]+kEff); i++){
1232  m_mapEff[dir][i]=i-m_deg[dir];
1233  }
1234 
1235  for(int i=(m_deg[dir]+kEff); i<kTheo; i++){
1236  m_mapEff[dir][i]=kEff-1;
1237  }
1238  break;
1239 
1240  case CoordType::PERIODIC :
1241 
1242  m_deg[dir] = std::min(m_deg[dir], nn-1);
1243  nEff = nn + m_deg[dir] - 1;
1244  kEff = nEff -m_deg[dir] + 1;
1245  kTheo = nEff +m_deg[dir] + 1;
1246  m_knots[dir].resize(kTheo);
1247  m_mapEff[dir].resize(kTheo,0);
1248 
1249  //set knots grid in the dir space considered 1 for this example
1250 
1251  m_knots[dir][m_deg[dir]] = 0.0;
1252  for(int j=0; j<=m_deg[dir]-1; ++j){
1253  m_knots[dir][m_deg[dir]] += equinode[j]/((double) m_deg[dir]);
1254  }
1255  if(abs(m_knots[dir][m_deg[dir]])<1.e-12) m_knots[dir][m_deg[dir]] = 0.0;
1256 
1257  for(int i=1; i<kEff; ++i){
1258  m_knots[dir][i+m_deg[dir]] = 0.0;
1259  for(int j=i; j<=i+m_deg[dir]-1; ++j){
1260  m_knots[dir][i+m_deg[dir]] += equinode[j]/((double) m_deg[dir]);
1261  }
1262  }
1263 
1264  kend = m_deg[dir] + kEff-1;
1265  //unclamp the other nodes
1266  for(int i=0; i<m_deg[dir]; ++i){
1267  m_knots[dir][m_deg[dir]-i-1] = m_knots[dir][m_deg[dir]-i] - (m_knots[dir][kend-i] - m_knots[dir][kend-i-1]);
1268  m_knots[dir][kend +1 +i] = m_knots[dir][kend + i] + (m_knots[dir][m_deg[dir]+i+1] - m_knots[dir][m_deg[dir]+i]);
1269  }
1270 
1271  for(int i=0; i<kTheo; i++){
1272  m_mapEff[dir][i]=i;
1273  }
1274  break;
1275 
1276  case CoordType::SYMMETRIC :
1277 
1278  m_deg[dir] = std::min(m_deg[dir], nn-1);
1279  nEff = nn + m_deg[dir]-1;
1280  kEff = nEff -m_deg[dir] + 1;
1281  kTheo = nEff +m_deg[dir] + 1;
1282  m_knots[dir].resize(kTheo);
1283  m_mapEff[dir].resize(kTheo,0);
1284 
1285  //set knots grid in the dir space considered 1 for this example
1286 
1287  m_knots[dir][m_deg[dir]] = 0.0;
1288  for(int j=0; j<=m_deg[dir]-1; ++j){
1289  m_knots[dir][m_deg[dir]] += equinode[j]/((double) m_deg[dir]);
1290  }
1291  if(std::abs(m_knots[dir][m_deg[dir]])<1.e-12) m_knots[dir][m_deg[dir]] = 0.0;
1292 
1293  for(int i=1; i<kEff; ++i){
1294  m_knots[dir][i+m_deg[dir]] = 0.0;
1295  for(int j=i; j<=i+m_deg[dir]-1; ++j){
1296  m_knots[dir][i+m_deg[dir]] += equinode[j]/((double) m_deg[dir]);
1297  }
1298  }
1299 
1300  kend = m_deg[dir] + kEff-1;
1301  //unclamp the other nodes
1302  for(int i=0; i<m_deg[dir]; ++i){
1303  m_knots[dir][m_deg[dir]-i-1] = m_knots[dir][m_deg[dir]-i] - (m_knots[dir][kend-i] - m_knots[dir][kend-i-1]);
1304  m_knots[dir][kend +1 +i] = m_knots[dir][kend + i] + (m_knots[dir][m_deg[dir]+i+1] - m_knots[dir][m_deg[dir]+i]);
1305  }
1306 
1307  for(int i=0; i<kTheo; i++){
1308  m_mapEff[dir][i]=i;
1309  }
1310  break;
1311 
1312 
1313  case CoordType::UNCLAMPED :
1314 
1315  m_deg[dir] = std::min(m_deg[dir], nn-1);
1316  kEff = nn - m_deg[dir] + 1;
1317  kTheo = nn + m_deg[dir] + 1;
1318  m_knots[dir].resize(kTheo);
1319  m_mapEff[dir].resize(kTheo,0);
1320 
1321  kend = m_deg[dir] + kEff-1;
1322  //set knots grid in the dir space considered 1 for this example
1323  m_knots[dir][m_deg[dir]] = equinode[0];
1324  m_knots[dir][kend] = equinode[equinode.size()-1] + tol;
1325 
1326  for(int i=1; i<kEff-1; ++i){
1327  m_knots[dir][m_deg[dir]+i] = 0.0;
1328  for(int j=i; j<=i+m_deg[dir]-1; ++j){
1329  m_knots[dir][m_deg[dir]+i] += equinode[j]/((double) m_deg[dir]);
1330  }
1331  }
1332 
1333  //unclamp the other nodes
1334  for(int i=0; i<m_deg[dir]; ++i){
1335  m_knots[dir][m_deg[dir]-i-1] = m_knots[dir][m_deg[dir]-i] - (m_knots[dir][kend-i] - m_knots[dir][kend-i-1]);
1336  m_knots[dir][kend +1 +i] = m_knots[dir][kend + i] + (m_knots[dir][m_deg[dir]+i+1] - m_knots[dir][m_deg[dir]+i]);
1337  }
1338 
1339  for(int i=0; i<kTheo; i++){
1340  m_mapEff[dir][i]=i;
1341  }
1342  break;
1343 
1344  default: //never been reached
1345  break;
1346  }
1347 
1348  setMapNodes(dir);
1349 
1350 };
1351 
1358 int
1359 FFDLattice::getKnotInterval(double coord, int dir){
1360 
1361  int size = m_knots[dir].size();
1362  if(coord< m_knots[dir][0] ){ return(getTheoreticalKnotIndex(0, dir));}
1363  if(coord >= m_knots[dir][size-1]){ return(getTheoreticalKnotIndex(size-2, dir));}
1364 
1365  int low = 0;
1366  int high = size-1;
1367  int mid = (low + high)/2;
1368  while( coord < m_knots[dir][mid] || coord>= m_knots[dir][mid+1]){
1369  if(coord < m_knots[dir][mid]) {high=mid;}
1370  else {low=mid;}
1371  mid = (low+high)/2;
1372  }
1373  return(getTheoreticalKnotIndex(mid, dir));
1374 };
1375 
1381 double
1382 FFDLattice::getKnotValue(int index, int dir){
1383  int target = getKnotIndex(index, dir);
1384  if(target ==-1){return(-1.0);}
1385  return(m_knots[dir][target]);
1386 };
1387 
1393 int
1394 FFDLattice::getKnotIndex(int index ,int dir){
1395  if(index < 0 || index>=(int)m_mapEff[dir].size()) return -1;
1396  return(m_mapEff[dir][index]);
1397 };
1398 
1404 int
1405 FFDLattice::getTheoreticalKnotIndex(int locIndex,int dir){
1406  if(locIndex <0 || locIndex >= (int)m_knots[dir].size()){return(-1);}
1407 
1408  // search from the end your m_mapEff vector
1409  ivector1D::reverse_iterator it = find(m_mapEff[dir].rbegin(), m_mapEff[dir].rend(), locIndex);
1410  int result = std::distance(m_mapEff[dir].begin(), (it.base()-1));
1411  return(result);
1412 };
1413 
1417 void FFDLattice::resizeMapDof(){
1418  Lattice::resizeMapDof();
1419  m_displ.clear();
1420  m_displ.resize(m_np, darray3E{{0.0,0.0,0.0}});
1421 }
1422 
1427 void
1428 FFDLattice::plotOptionalResults(){
1429 
1430  std::string dir = m_outputPlot;
1431  std::string nameGrid = m_name+"GRID";
1432  // std::string nameCloud = m_name+"CLOUD";
1433  std::string nameGridD = m_name+"GRID_deformed";
1434  // std::string nameCloudD = m_name+"CLOUD_deformed";
1435 
1436 #if MIMMO_ENABLE_MPI
1437  // Only master rank writes the lattice mesh
1438  if (getRank() == 0)
1439 #endif
1440  {
1441  plotGrid(dir, nameGrid, getId(), true, false );
1442  // plotCloud(dir, nameCloud, getClassCounter(), true, false );
1443  plotGrid(dir, nameGridD, getId(), true, true );
1444  // plotCloud(dir, nameCloudD, getClassCounter(), true, true );
1445  }
1446 }
1447 
1451 dvecarr3E
1452 FFDLattice::recoverFullGridDispl(){
1453 
1454  iarray3E dim = getDimension();
1455  int size = dim[0]*dim[1]*dim[2];
1456  dvecarr3E result(size);
1457  for(int i=0; i<size; ++i){
1458  result[i] = m_displ[m_intMapDOF[i]];
1459  }
1460  return(result);
1461 };
1462 
1464 dvector1D FFDLattice::recoverFullNodeWeights(){
1465 
1466  iarray3E dim = getDimension();
1467  int size = dim[0]*dim[1]*dim[2];
1468  dvector1D result(size);
1469  for(int i=0; i<size; ++i){
1470  result[i] = m_weights[m_intMapDOF[i]];
1471  }
1472  return(result);
1473 };
1474 
1477 void
1478 FFDLattice::setMapNodes( int ind){
1479 
1480  int dimdir = getDimension()[ind];
1481  int nn,preNNumb,postNNumb, pInd;
1482  m_mapNodes[ind].clear();
1483 
1484  switch(getCoordType(ind)){
1485  case CoordType::PERIODIC :
1486 
1487  nn = dimdir+m_deg[ind]-1;
1488  m_mapNodes[ind].resize(nn+1);
1489 
1490  preNNumb = (m_deg[ind]-1)/2 + (m_deg[ind]-1)%2;
1491  postNNumb = (m_deg[ind]-1) - preNNumb;
1492 
1493  // set the other internal loads
1494  for(int i=0; i<dimdir; ++i){
1495  m_mapNodes[ind][i+preNNumb] = i;
1496  }
1497 
1498  //postpend the first preNNumb loads
1499  pInd = dimdir - preNNumb -1;
1500  for(int i=0; i<preNNumb; ++i){
1501  m_mapNodes[ind][i] = pInd + i;
1502  }
1503  //prepend the last postNNumb loads.
1504  pInd = 1;
1505  for(int i=0; i<=postNNumb; ++i){
1506  m_mapNodes[ind][i+preNNumb+dimdir] = pInd+i;
1507  }
1508  break;
1509 
1510  case CoordType::SYMMETRIC :
1511 
1512  nn = dimdir+m_deg[ind]-1;
1513  m_mapNodes[ind].resize(nn+1);
1514 
1515  preNNumb = (m_deg[ind]-1)/2 + (m_deg[ind]-1)%2;
1516  postNNumb = (m_deg[ind]-1) - preNNumb;
1517 
1518  // set the other internal loads
1519  for(int i=0; i<dimdir; ++i){
1520  m_mapNodes[ind][i+preNNumb] = i;
1521  }
1522 
1523  //prepend symmetrically loads
1524  for(int i=0; i<preNNumb; ++i){
1525  m_mapNodes[ind][preNNumb -1 - i] = (i+1)%(dimdir-1);
1526  }
1527  //postpend symmetrically loads.
1528  for(int i=0; i<=postNNumb; ++i){
1529  m_mapNodes[ind][i+preNNumb+dimdir] = (dimdir-2-i)%(dimdir-1);
1530  }
1531  break;
1532 
1533  default:
1534  m_mapNodes[ind].resize(dimdir);
1535  for (int i=0; i<dimdir; ++i){
1536  m_mapNodes[ind][i] = i;
1537  }
1538  break;
1539  }
1540 };
1541 
1544 void
1545 FFDLattice::orderDimension(){
1546 
1547  std::map<std::pair<int,int>, int > mapsort;
1548  mapsort[std::make_pair(m_nx,0)] = 0;
1549  mapsort[std::make_pair(m_ny,1)] = 1;
1550  mapsort[std::make_pair(m_nz,2)] = 2;
1551 
1552  int i=0;
1553  for (std::map<std::pair<int,int>, int >::iterator it = mapsort.begin(); it != mapsort.end(); ++it){
1554  m_mapdeg[i] = it->second;
1555  i++;
1556  }
1557 
1558 };
1559 
1564 bool
1565 FFDLattice::build(){
1566  bool check = Lattice::build();
1567  //check degrees;
1568  m_deg[0] = std::min(m_nx, std::max(1, m_deg[0]));
1569  m_deg[1] = std::min(m_ny, std::max(1, m_deg[1]));
1570  m_deg[2] = std::min(m_nz, std::max(1, m_deg[2]));
1571 
1572  m_weights.clear();
1573  m_weights.resize(m_np, 1.0);
1574 
1575  m_displ.resize(m_np, {{0.0,0.0,0.0}});
1576 
1577  std::unordered_map<int, double>::iterator it;
1578  //transfer data from collector of weights m_collect_wg
1579  for(it=m_collect_wg.begin(); it != m_collect_wg.end(); ++it){
1580  m_weights[it->first] = it->second;
1581  }
1582  //empty m_collect_wg
1583  m_collect_wg.clear();
1584 
1585  setKnotsStructure();
1586  orderDimension();
1587  return check;
1588 };
1589 
1595 void
1596 FFDLattice::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
1597 
1598 
1599  Lattice::absorbSectionXML(slotXML, name);
1600 
1601 
1602  if(slotXML.hasOption("CoordType")){
1603  std::string input = slotXML.get("CoordType");
1604  std::stringstream ss(bitpit::utils::string::trim(input));
1605  std::string temp;
1606  for(int i=0; i<3; ++i){
1607  ss>>temp;
1608  temp = bitpit::utils::string::trim(temp);
1609  if(temp == "SYMMETRIC"){
1610  setCoordType(CoordType::SYMMETRIC,i);
1611  }else if(temp =="UNCLAMPED"){
1612  setCoordType(CoordType::UNCLAMPED,i);
1613  }else if(temp =="PERIODIC"){
1614  setCoordType(CoordType::PERIODIC,i);
1615  }else{
1616  setCoordType(CoordType::CLAMPED,i);
1617  }
1618  }
1619  };
1620 
1621  if(slotXML.hasOption("Degrees")){
1622  std::string input = slotXML.get("Degrees");
1623  input = bitpit::utils::string::trim(input);
1624  iarray3E temp = {{1,1,1}};
1625  if(!input.empty()){
1626  std::stringstream ss(input);
1627  for(auto &val : temp) ss>>val;
1628  }
1629  setDegrees(temp);
1630  };
1631 
1632  if(slotXML.hasOption("DisplGlobal")){
1633  std::string input = slotXML.get("DisplGlobal");
1634  input = bitpit::utils::string::trim(input);
1635  bool temp = false;
1636  if(!input.empty()){
1637  std::stringstream ss(input);
1638  ss>>temp;
1639  }
1640  setDisplGlobal(temp);
1641  };
1642 
1643 };
1644 
1650 void
1651 FFDLattice::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
1652 
1653  Lattice::flushSectionXML(slotXML, name);
1654 
1655  {std::stringstream ss;
1656 
1657  for(int i=0; i<3; ++i){
1658  std::string towrite = "CLAMPED";
1659  if(getCoordType()[i] == CoordType::SYMMETRIC){
1660  towrite = "SYMMETRIC";
1661  } else if(getCoordType()[i] == CoordType::UNCLAMPED){
1662  towrite = "UNCLAMPED";
1663  } else if(getCoordType()[i] == CoordType::PERIODIC){
1664  towrite = "PERIODIC";
1665  }
1666  ss<<towrite<<'\t';
1667  }
1668  slotXML.set("CoordType", ss.str());
1669  }
1670 
1671  {
1672  std::stringstream ss;
1673  ss<<getDegrees()[0]<<'\t'<<getDegrees()[1]<<'\t'<<getDegrees()[2];
1674  slotXML.set("Degrees", ss.str());
1675  }
1676 
1677  {
1678  slotXML.set("DisplGlobal", std::to_string(int(isDisplGlobal())));
1679  }
1680 
1681 };
1682 
1683 }
Abstract Interface class for Elementary Shape Representation.
Definition: BasicShapes.hpp:91
#define M_GDISPLS
std::array< int, 3 > iarray3E
ivector2D m_mapNodes
Definition: FFDLattice.hpp:141
void setDimension(ivector1D dim)
darray3E getGlobalPoint(int)
void swap(FFDLattice &) noexcept
Definition: FFDLattice.cpp:97
#define M_DISPLS
FFDLattice & operator=(FFDLattice other)
Definition: FFDLattice.cpp:88
CoordType
Specify type of conditions to distribute NURBS nodes in a given coordinate of the shape.
Definition: BasicShapes.hpp:49
void buildPorts()
Definition: Lattice.cpp:86
iarray3E getDegrees()
Definition: FFDLattice.cpp:224
std::vector< darray3E > dvecarr3E
void returnKnotsStructure(dvector2D &, ivector2D &)
Definition: FFDLattice.cpp:194
void setDisplacements(dvecarr3E displacements)
Definition: FFDLattice.cpp:284
void setDisplGlobal(bool flag)
Definition: FFDLattice.cpp:298
void setCoordType(CoordType, int)
std::unique_ptr< BasicShape > m_shape
Definition: BasicMeshes.hpp:47
std::vector< long > livector1D
void setOrigin(darray3E origin)
int accessPointIndex(int i, int j, int k)
ShapeType getShapeType()
void setDegrees(iarray3E curveDegrees)
Definition: FFDLattice.cpp:273
const BasicShape * getShape() const
dmpvector1D * getFilter()
Definition: FFDLattice.cpp:245
void warningXML(bitpit::Logger *log, std::string name)
livector1D includeCloudPoints(const dvecarr3E &)
void setNodalWeight(double, int)
Definition: FFDLattice.cpp:453
void setShape(ShapeType type=ShapeType::CUBE)
dvector1D m_weights
Definition: FFDLattice.hpp:139
std::array< CoordType, 3 > getCoordType()
int accessDOFFromGrid(int index)
Definition: Lattice.cpp:172
std::vector< int > ivector1D
void plotCloud(std::string directory, std::string filename, int counter, bool binary, bool deformed)
Definition: FFDLattice.cpp:546
dmpvecarr3E * getDeformation()
Definition: FFDLattice.cpp:254
void plotGrid(std::string directory, std::string filename, int counter, bool binary, bool deformed)
Definition: FFDLattice.cpp:506
std::vector< double > dvector1D
virtual ~FFDLattice()
Definition: FFDLattice.cpp:65
iarray3E getDimension()
ShapeType
Identifies the type of elemental shape supported by BasicShape class.
Definition: BasicShapes.hpp:38
#define M_NURBSWEIGHTS
ivector2D m_mapEff
Definition: FFDLattice.hpp:138
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
void swap(Lattice &) noexcept
Definition: Lattice.cpp:74
void setFilter(dmpvector1D *)
Definition: FFDLattice.cpp:489
#define M_DEG
#define M_NURBSCOORDTYPE
dvecarr3E * getDisplacements()
Definition: FFDLattice.cpp:236
std::vector< ivector1D > ivector2D
void plotCloud(std::string &, std::string, int, bool, const ivector1D &labels, dvecarr3E *extPoints=nullptr)
std::vector< dvector1D > dvector2D
void setLattice(darray3E &origin, darray3E &span, ShapeType, iarray3E &dimensions, iarray3E &degrees)
Definition: FFDLattice.cpp:316
void setDataLocation(MPVLocation loc)
std::array< double, 3 > darray3E
void clearLattice()
Definition: Lattice.cpp:115
void setSpan(double, double, double)
dmpvecarr3E m_gdispl
Definition: FFDLattice.hpp:142
ivector1D getKnotsDimension()
Definition: FFDLattice.cpp:164
dvecarr3E convertDisplToXYZ()
Definition: FFDLattice.cpp:756
MimmoSharedPointer is a custom implementation of shared pointer.
MimmoSharedPointer< MimmoObject > getGeometry()
Free Form Deformation of a 3D surface and point clouds, with structured lattice.
Definition: FFDLattice.hpp:133
dvector1D getWeights()
Definition: FFDLattice.cpp:184
void plotGrid(std::string &, std::string, int, bool, const ivector1D &labels, dvecarr3E *extPoints=nullptr)
Structured 3D Cartesian Mesh.
Definition: Lattice.hpp:103
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
#define M_FILTER
virtual bool build()