MimmoGeometry.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 "MimmoGeometry.hpp"
25 #include "VTUGridReader.hpp"
26 #include "VTUGridWriterASCII.hpp"
27 #include <iostream>
28 
29 namespace mimmo {
30 
41  m_name = "mimmo.Geometry";
42  setDefaults();
43  setIOMode(mode);
44 }
45 
50 MimmoGeometry::MimmoGeometry(const bitpit::Config::Section & rootXML){
51 
52  m_name = "mimmo.Geometry";
53  setDefaults();
54 
55  std::string fallback_name = "ClassNONE";
56  std::string input = rootXML.get("ClassName", fallback_name);
57  input = bitpit::utils::string::trim(input);
58 
59  std::string fallback_name2 = "READ";
60  std::string input2 = rootXML.get("IOMode", fallback_name2);
61  input2 = bitpit::utils::string::trim(input2);
62 
64  if(input2 == "WRITE") setIOMode(IOMode::WRITE);
65  if(input2 == "CONVERT") setIOMode(IOMode::CONVERT);
66 
67  if(input == "mimmo.Geometry"){
68  absorbSectionXML(rootXML);
69  }else{
71  };
72 }
73 
77  clear();
78 };
79 
85  m_rinfo = other.m_rinfo;
86  m_winfo = other.m_winfo;
87  m_read = other.m_read;
88  m_write = other.m_write;
89  m_wformat = other.m_wformat;
90  m_codex = other.m_codex;
93  m_refPID = other.m_refPID;
95  m_tolerance = other.m_tolerance;
96  m_clean = other.m_clean;
98 };
99 
106  swap(other);
107  return *this;
108 };
109 
115 {
116  std::swap(m_rinfo, x.m_rinfo);
117  std::swap(m_winfo, x.m_winfo);
118  std::swap(m_read, x.m_read);
119  std::swap(m_write, x.m_write);
120  std::swap(m_wformat, x.m_wformat);
121  std::swap(m_codex, x.m_codex);
122  std::swap(m_buildSkdTree, x.m_buildSkdTree);
123  std::swap(m_buildKdTree, x.m_buildKdTree);
124  std::swap(m_refPID, x.m_refPID);
125  std::swap(m_multiSolidSTL, x.m_multiSolidSTL);
126  std::swap(m_tolerance, x.m_tolerance);
127  std::swap(m_clean, x.m_clean);
128  std::swap(m_parallelRestore, x.m_parallelRestore);
130 }
131 
135 void
137  bool built = true;
138  bool mandatory_input = (m_write && !m_read);
139  built = (built && createPortIn<MimmoSharedPointer<MimmoObject>, MimmoGeometry>(this, &mimmo::BaseManipulation::setGeometry, M_GEOM, mandatory_input));
140  built = (built && createPortOut<MimmoSharedPointer<MimmoObject>, MimmoGeometry>(this, &mimmo::BaseManipulation::getGeometry, M_GEOM));
141  m_arePortsBuilt = built;
142 }
143 
148  return this;
149 }
150 
154 void
156 
157  m_read = false;
158  m_rinfo.fname = "mimmoGeometry";
159  m_rinfo.ftype = static_cast<int>(FileType::STL);
160  m_rinfo.fdir = "./";
161 
162  m_write = false;
163  m_winfo.fname = "mimmoGeometry";
164  m_winfo.ftype = static_cast<int>(FileType::STL);
165  m_winfo.fdir = "./";
166 
167  m_wformat = Short;
168  m_codex = true;
169  m_buildSkdTree = false;
170  m_buildKdTree = false;
171  m_refPID = 0;
172  m_multiSolidSTL = false;
173  m_tolerance = 1.0e-06;
174  m_clean = true;
175  m_parallelRestore = MIMMO_ENABLE_MPI;
176 }
177 
178 
182 void
184  m_read = read;
185 }
186 
191 void
193  m_rinfo.ftype = type._to_integral();
194 }
195 
200 void
202  auto maybe_type = FileType::_from_integral_nothrow(type);
203  if(!maybe_type) type = 0;
204  m_rinfo.ftype = type;
205 }
206 
211 void
212 MimmoGeometry::setReadDir(std::string dir){
213  m_rinfo.fdir = dir;
214 }
215 
220 void
221 MimmoGeometry::setReadFilename(std::string filename){
222  m_rinfo.fname = filename;
223 }
224 
229 void
231  m_winfo.ftype = type._to_integral();
232 }
233 
238 void
240  auto maybe_type = FileType::_from_integral_nothrow(type);
241  if(!maybe_type) type = 0;
242  m_winfo.ftype = type;
243 }
244 
245 
249 void
251  m_write = write;
252 }
253 
258 void
259 MimmoGeometry::setWriteDir(std::string dir){
260  m_winfo.fdir = dir;
261 }
262 
267 void
268 MimmoGeometry::setWriteFilename(std::string filename){
269  m_winfo.fname = filename;
270 
271 }
272 
279 void
281  switch(mode){
283  _setRead();
284  _setWrite(false);
285  break;
287  _setRead(false);
288  _setWrite();
289  break;
291  _setRead();
292  _setWrite();
293  break;
294  default:
295  //never been reached
296  break;
297  }
298 }
299 
306 void
308  setIOMode(static_cast<MimmoGeometry::IOMode>(mode));
309 }
310 
314 void
315 MimmoGeometry::setDir(std::string dir){
316  m_rinfo.fdir = dir;
317  m_winfo.fdir = dir;
318 }
319 
323 void
324 MimmoGeometry::setFilename(std::string filename){
325  m_winfo.fname = filename;
326  m_rinfo.fname = filename;
327 }
328 
333 void
335  m_winfo.ftype = type._to_integral();
336  m_rinfo.ftype = type._to_integral();
337 }
338 
343 void
345  auto maybe_type = FileType::_from_integral_nothrow(type);
346  if(!maybe_type) type = 0;
347  m_winfo.ftype = type;
348  m_rinfo.ftype = type;
349 }
350 
357 void MimmoGeometry::setCodex(bool binary){
358  m_codex = binary;
359 }
360 
367  m_multiSolidSTL = multi;
368 }
369 
374 void
376  m_tolerance = std::max(1.0e-15, tol);
377 }
378 
383 void
385  m_clean = clean;
386 }
387 
394 void
395 MimmoGeometry::setParallelRestore(bool parallelRestore){
396  m_parallelRestore = parallelRestore;
397 }
398 
405 void
407  if(type > 4) type = 1;
408  int type_ = std::max(type,1);
409  m_geometry.reset(new MimmoObject(type_));
410 };
411 
417 bitpit::PiercedVector<bitpit::Vertex> *
419  return &(getGeometry()->getVertices());
420 };
421 
427 bitpit::PiercedVector<bitpit::Cell> * MimmoGeometry::getCells(){
428  return &(getGeometry()->getCells());
429 
430 };
431 
435 void
437  getGeometry()->setPID(pids);
438 };
439 
443 void
444 MimmoGeometry::setPID(std::unordered_map<long, long> pidsMap){
445  getGeometry()->setPID(pidsMap);
446 };
447 
455 void
457  m_refPID = std::max(long(0),pid);
458 }
459 
460 
465 void
467  m_buildSkdTree = build;
468 }
469 
474 void
476  m_buildKdTree = build;
477 }
478 
485  if(getGeometry() == nullptr) return true;
486  return getGeometry()->isEmpty();
487 }
488 
492 void
494  setDefaults();
496 };
497 
501 void
503  m_wformat = wform;
504 }
505 
509 bool
511 
512  //adjusting with reference pid;
513  {
514  auto locpids = getGeometry()->getCompactPID();
515  auto pidsMap = getGeometry()->getPIDTypeListWNames();
516  for( auto & val: locpids) val+=m_refPID;
517  setPID(locpids);
518  auto pids = getGeometry()->getPIDTypeList();
519  for( auto & val: pids) getGeometry()->setPIDName(val, pidsMap[val - m_refPID]);
520  //action completed, reset m_refPID to zero.
521  m_refPID = 0;
522  }
523 
524  //check writing filetype
525  if (!FileType::_from_integral_nothrow(m_winfo.ftype)){
526  return false;
527  }
528 
529  switch(FileType::_from_integral(m_winfo.ftype)){
530 
531  case FileType::STL :
532  //Export STL
533  {
534  auto pidsMap = getGeometry()->getPIDTypeListWNames();
535  std::unordered_map<int, std::string> mpp;
536  for(const auto & touple : pidsMap){
537  mpp[touple.first] = touple.second;
538  }
539  std::string name = (m_winfo.fdir+"/"+m_winfo.fname+".stl");
540  dynamic_cast<bitpit::SurfUnstructured*>(getGeometry()->getPatch())->exportSTL(name, m_codex, m_multiSolidSTL, &mpp);
541  return true;
542  }
543  break;
544 
545 
546  case FileType::SURFVTU :
547  case FileType::VOLVTU :
548  case FileType::CURVEVTU:
549  case FileType::PCVTU:
550  //Export Surface/Volume/3DCurve VTU
551  {
552  if(!m_codex){
553  VTUFlushStreamerASCII streamer;
554  VTUGridWriterASCII vtkascii(streamer, *(getGeometry()->getPatch()) );
555  vtkascii.write(m_winfo.fdir+"/", m_winfo.fname);
556  }
557  else{
558  getGeometry()->getPatch()->getVTK().setCodex(bitpit::VTKFormat::APPENDED);
559  getGeometry()->getPatch()->getVTK().setDirectory(m_winfo.fdir+"/");
560  getGeometry()->getPatch()->getVTK().setName(m_winfo.fname);
561  getGeometry()->getPatch()->write();
562  }
563  return true;
564  }
565  break;
566 
567  case FileType::NAS :
568  //Export Nastran file - Id of vertex and cell cannot be 0 or negative. So all
569  // nas vertex/cell id etiquette are incremented by 1;
570  // same for PID: if 0 exists, pids are incremented by 1; if -1 exists are incremented by 2;
571  // Beware if id >= 10^8 nas format does not support it.
572  {
573  lilimap mapDataInv;
574  dvecarr3E points = getGeometry()->getVerticesCoords();
575  livector1D pointsID;
576  pointsID.reserve(points.size());
577  bitpit::PiercedVector<bitpit::Vertex> & vertices = getGeometry()->getVertices();
578  long id;
579  for(bitpit::Vertex & vv : vertices){
580  id = vv.getId();
581  mapDataInv[id] = id+1;
582  pointsID.push_back(id+1);
583  }
584  //return compactconnectivity using vertex map
585  livector2D connectivity = getGeometry()->getCompactConnectivity(mapDataInv);
586  livector1D elementsID;
587  elementsID.reserve(connectivity.size());
588  for(bitpit::Cell & cell : getGeometry()->getCells()){
589  elementsID.push_back(cell.getId()+1);
590  }
591  NastranInterface nastran;
592  nastran.setWFormat(m_wformat);
593  livector1D pids = getGeometry()->getCompactPID();
594  std::unordered_set<long> pidsset = getGeometry()->getPIDTypeList();
595  // pid cannot be negative or 0 in NAS.
596  if(pidsset.count(-1) > 0 || pidsset.count(0) > 0){
597  std::unordered_set<long> temp;
598  long offset = 1+ long(pidsset.count(-1)>0);
599  for(auto & val : pidsset){
600  temp.insert(val+offset);
601  }
602  std::swap(temp, pidsset);
603  for(long & val :pids){
604  val+=offset;
605  }
606  }
607  std::string namefile = m_winfo.fname;
608 #if MIMMO_ENABLE_MPI
609  // Only master rank 0 writes on file
610  if (getRank() == 0)
611 #endif
612  {
613  if (pids.size() == connectivity.size()){
614  nastran.write(m_winfo.fdir,namefile,points, pointsID, connectivity,elementsID, &pids, &pidsset);
615  }else{
616  nastran.write(m_winfo.fdir,namefile,points, pointsID, connectivity, elementsID);
617  }
618  }
619  return true;
620  }
621  break;
622 //
623 // case FileType::PCVTU :
624 // //Export Point Cloud VTU
625 // {
626 // dvecarr3E points = getGeometry()->getVerticesCoords();
627 // ivector2D connectivity(points.size(), ivector1D(1,0));
628 // int counter = 0;
629 // for(auto & c:connectivity){
630 // c[0] = counter;
631 // counter++;
632 // }
633 // bitpit::VTKUnstructuredGrid vtk(m_winfo.fdir, m_winfo.fname, bitpit::VTKElementType::VERTEX);
634 // vtk.setGeomData( bitpit::VTKUnstructuredField::POINTS, points) ;
635 // vtk.setGeomData( bitpit::VTKUnstructuredField::CONNECTIVITY, connectivity) ;
636 // vtk.setDimensions(connectivity.size(), points.size());
637 // if(!m_codex) vtk.setCodex(bitpit::VTKFormat::ASCII);
638 // else vtk.setCodex(bitpit::VTKFormat::APPENDED);
639 // vtk.write() ;
640 // return true;
641 // }
642 // break;
643 
644  case FileType::MIMMO :
645  //Export in mimmo (bitpit) dump format
646  {
647  int archiveVersion = 1;
648  std::string header = m_name;
649  std::string filename = (m_winfo.fdir+"/"+m_winfo.fname);
650 #if MIMMO_ENABLE_MPI
651  bitpit::OBinaryArchive binaryWriter(filename, "geomimmo", archiveVersion, header, getRank());
652 #else
653  bitpit::OBinaryArchive binaryWriter(filename, "geomimmo", archiveVersion, header);
654 #endif
655  getGeometry()->dump(binaryWriter.getStream());
656  binaryWriter.close();
657  return true;
658  }
659  break;
660 
661  default: //never been reached
662  break;
663  }
664 
665  return false;
666 };
667 
672 bool
674 
675  //check reading filetype
676  if (!FileType::_from_integral_nothrow(m_rinfo.ftype)){
677  return false;
678  }
679 
680  switch(FileType::_from_integral(m_rinfo.ftype)){
681 
682  //Import STL
683  case FileType::STL :
684  {
685  setGeometry(1);
686  std::string name;
687 #if MIMMO_ENABLE_MPI
688  if (getRank() == 0) {
689 #endif
690  {
691  name = m_rinfo.fdir+"/"+m_rinfo.fname+".stl";
692  bool check = fileExist(name);
693  if (!check){
694  name = m_rinfo.fdir+"/"+m_rinfo.fname+".STL";
695  check = fileExist(name);
696  if (!check) return false;
697  }
698  }
699 
700  std::ifstream in(name);
701  std::string ss, sstype;
702  std::getline(in,ss);
703  std::stringstream ins;
704  ins << ss;
705  ins >> sstype;
706  bool binary = true;
707  if (sstype == "solid" || sstype == "SOLID") binary = false;
708  in.close();
709 
710  std::unordered_map<int,std::string> mapPIDSolid;
711  dynamic_cast<bitpit::SurfUnstructured*>(getGeometry()->getPatch())->importSTL(name, binary, 0, false, &mapPIDSolid);
712 
713  //count PID if multi-solid
714  auto & mapset = getGeometry()->getPIDTypeList();
715  for(const auto & cell : getGeometry()->getCells() ){
716  mapset.insert(cell.getPID());
717  }
718  std::unordered_map<long, std::string> & mapWNames = getGeometry()->getPIDTypeListWNames();
719  for(const auto & val :mapset ){
720  mapWNames[val] = mapPIDSolid[val];
721  }
722 #if MIMMO_ENABLE_MPI
723  }
724 #endif
725  }
726  break;
727 
728  case FileType::SURFVTU :
729  //Import Surface VTU meshes
730  {
731  setGeometry(1);
732  bool masterRankOnly = true;
733  std::string name = m_rinfo.fdir+"/"+m_rinfo.fname;
734  std::string extension = ".vtu";
735 #if MIMMO_ENABLE_MPI
736  if (getGeometry()->getProcessorCount() > 1){
737  //check for pvtu
738  extension = ".pvtu";
739  if(fileExist(name+extension)){
740  masterRankOnly = false;
741  }else{
742  //fallback to normal vtu.
743  extension = ".vtu";
744  }
745  }
746 #endif
747 
748  if (!fileExist(name+extension)) return false;
749 
750  VTUGridStreamer vtustreamer;
751  VTUGridReader input(m_rinfo.fdir, m_rinfo.fname, vtustreamer, *(getGeometry()->getPatch()), masterRankOnly);
752 
753  input.read() ;
754 
755  getGeometry()->resyncPID();
756  }
757  break;
758 
759  case FileType::VOLVTU :
760  //Import Volume VTU meshes
761  {
762  setGeometry(2);
763  bool masterRankOnly = true;
764  std::string name = m_rinfo.fdir+"/"+m_rinfo.fname;
765  std::string extension = ".vtu";
766 #if MIMMO_ENABLE_MPI
767  if (getGeometry()->getProcessorCount() > 1){
768  //check for pvtu
769  extension = ".pvtu";
770  if(fileExist(name+extension)){
771  masterRankOnly = false;
772  }else{
773  //fallback to normal vtu.
774  extension = ".vtu";
775  }
776  }
777 #endif
778 
779  if (!fileExist(name+extension)) return false;
780 
781  VTUGridStreamer vtustreamer;
782  VTUGridReader input(m_rinfo.fdir, m_rinfo.fname, vtustreamer, *(getGeometry()->getPatch()), masterRankOnly);
783 
784  input.read() ;
785 
786  getGeometry()->resyncPID();
787  }
788  break;
789 
790  case FileType::NAS :
791  //Import Surface NAS
792  {
793  setGeometry(1);
794 #if MIMMO_ENABLE_MPI
795  if (getRank() == 0) {
796 #endif
797  bool check = fileExist(m_rinfo.fdir+"/"+m_rinfo.fname+".nas");
798  if (!check) return false;
799 
800  dvecarr3E Ipoints ;
801  livector2D Iconnectivity ;
802  livector1D pointsID;
803  livector1D cellsID;
804 
805  NastranInterface nastran;
806  nastran.setWFormat(m_wformat);
807 
808  livector1D pids;
809  nastran.read(m_rinfo.fdir, m_rinfo.fname, Ipoints, pointsID, Iconnectivity, cellsID, pids );
810 
811  bitpit::ElementType eltype;
812 
813  int sizeV, sizeC;
814  sizeV = Ipoints.size();
815  sizeC = Iconnectivity.size();
816  getGeometry()->getPatch()->reserveVertices(sizeV);
817  getGeometry()->getPatch()->reserveCells(sizeC);
818 
819  int counter = 0;
820  for(const auto & vv : Ipoints){
821  getGeometry()->addVertex(vv, pointsID[counter]);
822  ++counter;
823  }
824  counter = 0;
825  for(const auto & cc : Iconnectivity) {
826  eltype = bitpit::ElementType::UNDEFINED;
827  std::size_t ccsize = cc.size();
828  if(ccsize == 1) eltype = bitpit::ElementType::VERTEX;
829  if(ccsize == 2) eltype = bitpit::ElementType::LINE;
830  if(ccsize == 3) eltype = bitpit::ElementType::TRIANGLE;
831  if(ccsize == 4) eltype = bitpit::ElementType::QUAD;
832  if(ccsize > 4) eltype = bitpit::ElementType::POLYGON;
833 
834  getGeometry()->addConnectedCell(cc, eltype, cellsID[counter]);
835  ++counter;
836  }
837  getGeometry()->setPID(pids);
838 #if MIMMO_ENABLE_MPI
839  }
840 #endif
841  }
842  break;
843 
844  //Import point cloud from vtu
845  case FileType::PCVTU :
846  {
847  setGeometry(3);
848  bool masterRankOnly = true;
849  std::string name = m_rinfo.fdir+"/"+m_rinfo.fname;
850  std::string extension = ".vtu";
851 #if MIMMO_ENABLE_MPI
852  if (getGeometry()->getProcessorCount() > 1){
853  //check for pvtu
854  extension = ".pvtu";
855  if(fileExist(name+extension)){
856  masterRankOnly = false;
857  }else{
858  //fallback to normal vtu.
859  extension = ".vtu";
860  }
861  }
862 #endif
863 
864  if (!fileExist(name+extension)) return false;
865 
866  VTUGridStreamer vtustreamer;
867  VTUGridReader input(m_rinfo.fdir, m_rinfo.fname, vtustreamer, *(getGeometry()->getPatch()), masterRankOnly);
868 
869  input.read() ;
870  getGeometry()->resyncPID();
871  }
872  break;
873 
874  case FileType::CURVEVTU :
875  //Import 3D Curve VTU
876  {
877  setGeometry(4);
878  bool masterRankOnly = true;
879  std::string name = m_rinfo.fdir+"/"+m_rinfo.fname;
880  std::string extension = ".vtu";
881 #if MIMMO_ENABLE_MPI
882  if (getGeometry()->getProcessorCount() > 1){
883  //check for pvtu
884  extension = ".pvtu";
885  if(fileExist(name+extension)){
886  masterRankOnly = false;
887  }else{
888  //fallback to normal vtu.
889  extension = ".vtu";
890  }
891  }
892 #endif
893 
894  if (!fileExist(name+extension)) return false;
895 
896  VTUGridStreamer vtustreamer;
897  VTUGridReader input(m_rinfo.fdir, m_rinfo.fname, vtustreamer, *(getGeometry()->getPatch()), masterRankOnly);
898 
899  input.read() ;
900 
901  getGeometry()->resyncPID();
902  }
903  break;
904 
905  case FileType::MIMMO :
906  //Import in mimmo (bitpit) restore format
907  {
908  std::string filename = (m_rinfo.fdir+"/"+m_rinfo.fname);
909 #if MIMMO_ENABLE_MPI
910  bitpit::IBinaryArchive binaryReader(filename,"geomimmo", getRank());
911 #else
912  bitpit::IBinaryArchive binaryReader(filename, "geomimmo");
913 #endif
914 
915  // Reset to a generic geometry with the correct parallel propriety
917  m_geometry->restore(binaryReader.getStream());
918  binaryReader.close();
919  }
920  break;
921 
922  default: //never been reached
923  break;
924 
925  }
926 
927  // set Tolerance and clean geometry
928  getGeometry()->setTolerance(m_tolerance);
929  if (m_clean){
930  getGeometry()->cleanGeometry();
931  }
932 
933  //adjusting with reference pid;
934  auto locpids = getGeometry()->getCompactPID();
935  auto pidsMap = getGeometry()->getPIDTypeListWNames();
936  for( auto & val: locpids) val+=m_refPID;
937  setPID(locpids);
938  auto pids = getGeometry()->getPIDTypeList();
939  for( auto & val: pids) getGeometry()->setPIDName(val, pidsMap[val - m_refPID]);
940 
941  //action completed, reset m_refPID to zero.
942  m_refPID = 0;
943 
944  // Set all the sync status variables to unsync
945  getGeometry()->setUnsyncAll();
946 
947  return true;
948 };
949 
956 bool
957 MimmoGeometry::fileExist(const std::string & filename){
958  std::ifstream tryfile(filename);
959  bool check = tryfile.good();
960  tryfile.close();
961  return check;
962 }
963 
968 void
970  bool check = true;
971  // Read geometry
972  if (m_read){
973  check = read();
974  if (!check){
975  (*m_log) << m_name << " error: file not found : "<< m_rinfo.fname << std::endl;
976  (*m_log) << " " << std::endl;
977  throw std::runtime_error (m_name + " : file not found : " + m_rinfo.fname);
978  }
979 
980  // Update geometry
981  getGeometry()->update();
982 
983  if (m_buildSkdTree) getGeometry()->buildSkdTree();
984  if (m_buildKdTree) getGeometry()->buildKdTree();
985  }
986  check = true;
987  // Write geometry
988  if (m_write){
989  check = write();
990  if (!check){
991  (*m_log) << m_name << " error: write not done : geometry not linked " << std::endl;
992  (*m_log) << " " << std::endl;
993  return;
994  }
995  }
996 }
997 
1003 void
1004 MimmoGeometry::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
1005 
1006  BITPIT_UNUSED(name);
1007 
1008  std::string input;
1009 
1010  BaseManipulation::absorbSectionXML(slotXML, name);
1011 
1012  if(slotXML.hasOption("FileType")){
1013  input = slotXML.get("FileType");
1014  input = bitpit::utils::string::trim(input);
1015  if(!input.empty()){
1016  for(auto c: FileType::_values()){
1017  if(input == c._to_string()){
1018  setFileType(c);
1019  }
1020  }
1021  }else{
1022  setFileType(0);
1023  }
1024  };
1025 
1026  if(slotXML.hasOption("ReadFileType")){
1027  input = slotXML.get("ReadFileType");
1028  input = bitpit::utils::string::trim(input);
1029  if(!input.empty()){
1030  for(auto c: FileType::_values()){
1031  if(input == c._to_string()){
1032  setReadFileType(c);
1033  }
1034  }
1035  }
1036  };
1037 
1038  if(slotXML.hasOption("WriteFileType")){
1039  input = slotXML.get("WriteFileType");
1040  input = bitpit::utils::string::trim(input);
1041  if(!input.empty()){
1042  for(auto c: FileType::_values()){
1043  if(input == c._to_string()){
1044  setWriteFileType(c);
1045  }
1046  }
1047  }
1048  };
1049 
1050  if(slotXML.hasOption("Dir")){
1051  input = slotXML.get("Dir");
1052  input = bitpit::utils::string::trim(input);
1053  if(input.empty()) input = "./";
1054  setDir(input);
1055  };
1056 
1057 
1058  if(slotXML.hasOption("Filename")){
1059  input = slotXML.get("Filename");
1060  input = bitpit::utils::string::trim(input);
1061  if(input.empty()) input = "mimmoGeometry";
1062  setFilename(input);
1063  };
1064 
1065  if(slotXML.hasOption("ReadDir")){
1066  input = slotXML.get("ReadDir");
1067  input = bitpit::utils::string::trim(input);
1068  if(!input.empty())
1069  setReadDir(input);
1070  };
1071 
1072 
1073  if(slotXML.hasOption("ReadFilename")){
1074  input = slotXML.get("ReadFilename");
1075  input = bitpit::utils::string::trim(input);
1076  if(!input.empty())
1077  setReadFilename(input);
1078  };
1079 
1080  if(slotXML.hasOption("WriteDir")){
1081  input = slotXML.get("WriteDir");
1082  input = bitpit::utils::string::trim(input);
1083  if(!input.empty())
1084  setWriteDir(input);
1085  };
1086 
1087 
1088  if(slotXML.hasOption("WriteFilename")){
1089  input = slotXML.get("WriteFilename");
1090  input = bitpit::utils::string::trim(input);
1091  if(!input.empty())
1092  setWriteFilename(input);
1093  };
1094 
1095  if(slotXML.hasOption("Codex")){
1096  input = slotXML.get("Codex");
1097  bool value = true;
1098  if(!input.empty()){
1099  std::stringstream ss(bitpit::utils::string::trim(input));
1100  ss >> value;
1101  }
1102  setCodex(value);
1103  };
1104 
1105  //to be deprecated BvTree field option. Substituted by SkdTree.
1106  if(slotXML.hasOption("BvTree")){
1107  input = slotXML.get("BvTree");
1108  bool value = false;
1109  if(!input.empty()){
1110  std::stringstream ss(bitpit::utils::string::trim(input));
1111  ss >> value;
1112  }
1113  setBuildSkdTree(value);
1114  };
1115 
1116  if(slotXML.hasOption("SkdTree")){
1117  input = slotXML.get("SkdTree");
1118  bool value = false;
1119  if(!input.empty()){
1120  std::stringstream ss(bitpit::utils::string::trim(input));
1121  ss >> value;
1122  }
1123  setBuildSkdTree(value);
1124  };
1125 
1126 
1127  if(slotXML.hasOption("KdTree")){
1128  input = slotXML.get("KdTree");
1129  bool value = false;
1130  if(!input.empty()){
1131  std::stringstream ss(bitpit::utils::string::trim(input));
1132  ss >> value;
1133  }
1134  setBuildKdTree(value);
1135  };
1136 
1137  if(slotXML.hasOption("AssignRefPID")){
1138  input = slotXML.get("AssignRefPID");
1139  long value = 0;
1140  if(!input.empty()){
1141  std::stringstream ss(bitpit::utils::string::trim(input));
1142  ss >> value;
1143  }
1144  setReferencePID(value);
1145  };
1146 
1147  if(slotXML.hasOption("WriteMultiSolidSTL")){
1148  input = slotXML.get("WriteMultiSolidSTL");
1149  bool value = true;
1150  if(!input.empty()){
1151  std::stringstream ss(bitpit::utils::string::trim(input));
1152  ss >> value;
1153  }
1154  setMultiSolidSTL(value);
1155  };
1156 
1157  if(slotXML.hasOption("Tolerance")){
1158  input = slotXML.get("Tolerance");
1159  double value = 1.0e-06;
1160  if(!input.empty()){
1161  std::stringstream ss(bitpit::utils::string::trim(input));
1162  ss >> value;
1163  setTolerance(value);
1164  }
1165  };
1166 
1167  if(slotXML.hasOption("Clean")){
1168  input = slotXML.get("Clean");
1169  bool value = true;
1170  if(!input.empty()){
1171  std::stringstream ss(bitpit::utils::string::trim(input));
1172  ss >> value;
1173  }
1174  setClean(value);
1175  };
1176 
1177  if(slotXML.hasOption("FormatNAS")){
1178  input = slotXML.get("FormatNAS");
1179  bool value = false;
1180  if(!input.empty()){
1181  std::stringstream ss(bitpit::utils::string::trim(input));
1182  ss >> value;
1183  }
1184  if(value){
1186  }else{
1188  }
1189  };
1190 
1191  if(slotXML.hasOption("ParallelRestore")){
1192  input = slotXML.get("ParallelRestore");
1193  bool value = true;
1194  if(!input.empty()){
1195  std::stringstream ss(bitpit::utils::string::trim(input));
1196  ss >> value;
1197  }
1198  setParallelRestore(value);
1199  };
1200 
1201 };
1202 
1208 void
1209 MimmoGeometry::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
1210 
1211  BITPIT_UNUSED(name);
1212 
1213  BaseManipulation::flushSectionXML(slotXML, name);
1214 
1215  std::string output;
1216 
1217  {
1218  std::string temp = "READ";
1219  if(m_read && m_write) temp = "CONVERT";
1220  if(!m_read && m_write) temp = "WRITE";
1221  slotXML.set("IOMode", temp);
1222  }
1223 
1224  if (m_read && m_write)
1225  {
1226  slotXML.set("ReadDir", m_rinfo.fdir);
1227  slotXML.set("ReadFilename", m_rinfo.fname);
1228  slotXML.set("WriteDir", m_winfo.fdir);
1229  slotXML.set("WriteFilename", m_winfo.fname);
1230  }
1231  else{
1232  slotXML.set("Dir", m_rinfo.fdir);
1233  slotXML.set("Filename", m_rinfo.fname);
1234  }
1235 
1236  if (m_read && m_write)
1237  {
1238  std::string temp = (FileType::_from_integral(m_rinfo.ftype))._to_string();
1239  slotXML.set("ReadFileType", temp);
1240  temp = (FileType::_from_integral(m_winfo.ftype))._to_string();
1241  slotXML.set("WriteFileType", temp);
1242  }
1243  else
1244  {
1245  std::string temp = (FileType::_from_integral(m_rinfo.ftype))._to_string();
1246  slotXML.set("FileType", temp);
1247  }
1248 
1249  output = std::to_string(m_codex);
1250  slotXML.set("Codex", output);
1251 
1252  output = std::to_string(m_buildSkdTree);
1253  slotXML.set("SkdTree", output);
1254 
1255  output = std::to_string(m_buildKdTree);
1256  slotXML.set("KdTree", output);
1257  slotXML.set("AssignRefPID", std::to_string(m_refPID));
1258  slotXML.set("WriteMultiSolidSTL", std::to_string(m_multiSolidSTL));
1259 
1260  std::stringstream ss;
1261  ss<<std::scientific<<m_tolerance;
1262  slotXML.set("Tolerance", ss.str());
1263 
1264  output = std::to_string(m_clean);
1265  slotXML.set("Clean", output);
1266  slotXML.set("FormatNAS", std::to_string(bool(m_wformat == WFORMAT::Long)));
1267 
1268  output = std::to_string(m_parallelRestore);
1269  slotXML.set("ParallelRestore", output);
1270 
1271 };
1272 
1273 
1274 
1275 //===============================//
1276 //====== NASTRAN INTERFACE ======//
1277 //===============================//
1278 
1283  // Enable grid points and surface elements by default
1284  enable(NastranElementType::GRID);
1285  enable(NastranElementType::CTRIA);
1286  enable(NastranElementType::CQUAD);
1287  disable(NastranElementType::CBAR);
1288  disable(NastranElementType::RBE2);
1289  disable(NastranElementType::RBE3);
1291 }
1292 
1298  m_wformat = wf;
1299 }
1300 
1306 void NastranInterface::writeKeyword(std::string key, std::ofstream& os){
1307  os.setf(std::ios_base::left);
1308  switch (m_wformat)
1309  {
1310  case Short:
1311  {
1312  os << std::setw(8) << key;
1313  break;
1314  }
1315  case Long:
1316  {
1317  os << std::setw(8) << std::string(key + '*');
1318  break;
1319  }
1320  }
1321  os.unsetf(std::ios_base::left);
1322 }
1323 
1330 void NastranInterface::writeCoord(const darray3E& p, const long& pointI, std::ofstream& os){
1331  // Fixed short/long formats:
1332  // 1 GRID
1333  // 2 ID : point ID - requires starting index of 1
1334  // 3 CP : co-ordinate system ID (blank)
1335  // 4 X1 : point x cp-ordinate
1336  // 5 X2 : point x cp-ordinate
1337  // 6 X3 : point x cp-ordinate
1338  // 7 CD : co-ordinate system for displacements (blank)
1339  // 8 PS : single point constraints (blank)
1340  // 9 SEID : super-element ID
1341 
1342  std::string separator_("");
1343  writeKeyword(std::string("GRID"), os);
1344  os << separator_;
1345  os.setf(std::ios_base::right);
1346  writeValue(pointI, os);
1347  os << separator_;
1348  writeValue("", os);
1349  os << separator_;
1350  writeValue(p[0], os);
1351  os << separator_;
1352  writeValue(p[1], os);
1353  os << separator_;
1354  switch (m_wformat)
1355  {
1356  case Short:
1357  {
1358  writeValue(p[2], os);
1359  os << nl;
1360  // os << setw(8) << p[2]
1361  // << nl;
1362  os.unsetf(std::ios_base::right);
1363  break;
1364  }
1365  case Long:
1366  {
1367  os << nl;
1368  os.unsetf(std::ios_base::right);
1369  writeKeyword("", os);
1370  os.setf(std::ios_base::right);
1371  writeValue(p[2], os);
1372  os << nl;
1373  break;
1374  }
1375  default:
1376  {
1377  throw std::runtime_error ("NastranInterface : Unknown writeFormat enumeration");
1378  }
1379  }
1380  os.unsetf(std::ios_base::right);
1381 }
1382 
1391 void NastranInterface::writeFace(std::string faceType, const livector1D& facePts, const long& nFace, std::ofstream& os,long PID){
1392  // Only valid surface elements are CTRIA3 and CQUAD4
1393 
1394  // Fixed short/long formats:
1395  // 1 CQUAD4
1396  // 2 EID : element ID
1397  // 3 PID : property element ID; default = EID (blank)
1398  // 4 G1 : grid point index - requires starting index of 1
1399  // 5 G2 : grid point index
1400  // 6 G3 : grid point index
1401  // 7 G4 : grid point index
1402  // 8 onwards - not used
1403 
1404  // For CTRIA3 elements, cols 7 onwards are not used
1405 
1406  WFORMAT wformat_ = m_wformat;
1407  m_wformat = Short;
1408  std::string separator_("");
1409  writeKeyword(faceType, os);
1410  os << separator_;
1411  os.setf(std::ios_base::right);
1412  writeValue(nFace, os);
1413  os << separator_;
1414  writeValue(PID, os);
1415  int fp1;
1416  switch (m_wformat)
1417  {
1418  case Short:
1419  {
1420  for (int i=0; i< (int)facePts.size(); i++)
1421  {
1422  fp1 = facePts[i];
1423  writeValue(fp1, os);
1424  }
1425 
1426  break;
1427  }
1428  case Long:
1429  {
1430  for (int i=0; i< (int)facePts.size(); i++)
1431  {
1432  fp1 = facePts[i];
1433  writeValue(fp1, os);
1434  // if (i == 1)
1435  // {
1436  // os << nl;
1437  // os.unsetf(std::ios_base::right);
1438  // writeKeyword("", os);
1439  // os.setf(std::ios_base::right);
1440  // }
1441  }
1442  break;
1443  }
1444  default:
1445  {
1446  std::cout << "Unknown writeFormat enumeration" << std::endl;
1447  throw std::runtime_error ("Unknown writeFormat enumeration");
1448  }
1449  }
1450  os << nl;
1451  os.unsetf(std::ios_base::right);
1452  m_wformat = wformat_;
1453 }
1454 
1465 bool NastranInterface::writeGeometry(dvecarr3E& points, livector1D& pointsID, livector2D& faces, livector1D & facesID,
1466  std::ofstream& os, livector1D* PIDS){
1467 
1468  if(points.size() != pointsID.size()) return false;
1469  if(faces.size() != facesID.size()) return false;
1470  bool flagpid = (PIDS != nullptr);
1471  if(flagpid && (PIDS->size() != faces.size())) return false;
1472  int counter = 0;
1473  for (const auto & p: points){
1474  writeCoord(p, pointsID[counter], os);
1475  ++counter;
1476  }
1477 
1478  counter = 0;
1479  for (const auto & f: faces){
1480  long PID = 1;
1481  if (flagpid) PID = (*PIDS)[counter];
1482  if (f.size() == 3){
1483  writeFace("CTRIA3", f, facesID[counter], os, PID);
1484  ++counter;
1485  }
1486  else if (f.size() == 4){
1487  writeFace("CQUAD4", f, facesID[counter], os, PID);
1488  ++counter;
1489  }else{
1490  std::cerr << "Warning NastranInterface::writeGeometry : unknown face format" << std::endl;
1491  }
1492  }
1493 
1494  return true;
1495 }
1496 
1502 void NastranInterface::writeFooter(std::ofstream& os, std::unordered_set<long>* PIDSSET){
1503  std::string separator_("");
1504  if (PIDSSET == nullptr){
1505  int PID = 1;
1506  writeKeyword("PSHELL", os);
1507  os << separator_;
1508  writeValue(PID, os);
1509  for (int i = 0; i < 6; i++)
1510  {
1511  // Dummy values
1512  long uno = 1;
1513  os << separator_;
1514  writeValue(uno, os);
1515  }
1516  os << nl;
1517  }
1518  else{
1519  for (std::unordered_set<long>::iterator it = PIDSSET->begin(); it != PIDSSET->end(); it++)
1520  {
1521  writeKeyword("PSHELL", os);
1522  int PID = (*it);
1523  os << separator_;
1524  writeValue(PID, os);
1525  for (int i = 0; i < 6; i++)
1526  {
1527  // Dummy values
1528  long uno = 1;
1529  os << separator_;
1530  writeValue(uno, os);
1531  }
1532  os << nl;
1533 
1534  }
1535  }
1536 
1537  writeKeyword("MAT1", os);
1538  os << separator_;
1539  int MID = 1;
1540  writeValue(MID, os);
1541  for (int i = 0; i < 7; i++)
1542  {
1543  // Dummy values
1544  os << separator_;
1545  writeValue("", os);
1546  }
1547  os << nl;
1548 }
1549 
1561 void NastranInterface::write(std::string& outputDir, std::string& surfaceName, dvecarr3E& points, livector1D & pointsID,
1562  livector2D& faces, livector1D & facesID, livector1D* PIDS, std::unordered_set<long>* PIDSSET){
1563 
1564  std::ofstream os(outputDir +"/"+surfaceName + ".nas");
1565  os << "TITLE=mimmo " << surfaceName << " mesh" << nl
1566  << "$" << nl
1567  << "BEGIN BULK" << nl;
1568  bool check = writeGeometry(points, pointsID, faces, facesID, os, PIDS);
1569  if(!check){
1570  throw std::runtime_error ("Error in NastranInterface::write : geometry mesh cannot be written");
1571  }
1572  writeFooter(os, PIDSSET);
1573  os << "ENDDATA" << std::endl;
1574 }
1575 
1576 //========READ====//
1587 void NastranInterface::read(std::string& inputDir, std::string& surfaceName, dvecarr3E& points, livector1D & pointsID,
1588  livector2D& faces, livector1D & facesID, livector1D& PIDS){
1589 
1590  std::ifstream is(inputDir +"/"+surfaceName + ".nas");
1591 
1592  points.clear();
1593  pointsID.clear();
1594  faces.clear();
1595  facesID.clear();
1596  PIDS.clear();
1597 
1598  long ipoint = 0;
1599  long iface = 0;
1600  darray3E point;
1601  livector1D face;
1602  long pid;
1603  std::string sread;
1604  std::string ssub = trim(sread.substr(0,8));
1605 
1606  while(!is.eof()){
1607  while(((ssub != "GRID" && ssub != "GRID*") || !isEnabled(NastranElementType::GRID)) &&
1608  ((ssub != "CTRIA3" && ssub != "CTRIA3*") || !isEnabled(NastranElementType::CTRIA)) &&
1609  ((ssub != "CQUAD4" && ssub != "CQUAD4*") || !isEnabled(NastranElementType::CQUAD)) &&
1610  (ssub != "RBE2" || !isEnabled(NastranElementType::RBE2)) &&
1611  (ssub != "RBE3" || !isEnabled(NastranElementType::RBE3)) &&
1612  (ssub != "CBAR" || !isEnabled(NastranElementType::CBAR)) &&
1613  !is.eof()){
1614  std::getline(is,sread);
1615  ssub = trim(sread.substr(0,8));
1616  }
1617  if(ssub == "GRID"){
1618  ipoint = stoi(sread.substr(8,8));
1619  point[0] = stod(convertVertex(trim(sread.substr(24,8))));
1620  point[1] = stod(convertVertex(trim(sread.substr(32,8))));
1621  point[2] = stod(convertVertex(trim(sread.substr(40,8))));
1622  points.push_back(point);
1623  pointsID.push_back(ipoint);
1624  std::getline(is,sread);
1625  ssub = trim(sread.substr(0,8));
1626  }
1627  else if(ssub == "GRID*"){
1628  ipoint = stoi(sread.substr(16,16));
1629  point[0] = stod(convertVertex(trim(sread.substr(48,16))));
1630  point[1] = stod(convertVertex(trim(sread.substr(64,16))));
1631  point[2] = stod(convertVertex(trim(sread.substr(80,16))));
1632  points.push_back(point);
1633  pointsID.push_back(ipoint);
1634  std::getline(is,sread);
1635  ssub = trim(sread.substr(0,8));
1636  }
1637  else if(ssub == "CTRIA3"){
1638  face.resize(3);
1639  iface = stoi(sread.substr(8,8));
1640  pid = stoi(sread.substr(16,8));
1641  face[0] = stoi(sread.substr(24,8));
1642  face[1] = stoi(sread.substr(32,8));
1643  face[2] = stoi(sread.substr(40,8));
1644  faces.push_back(face);
1645  facesID.push_back(iface);
1646  PIDS.push_back(pid);
1647  std::getline(is,sread);
1648  ssub = trim(sread.substr(0,8));
1649  }
1650  else if(ssub == "CTRIA3*"){
1651  face.resize(3);
1652  iface = stoi(sread.substr(16,16));
1653  pid = stoi(sread.substr(32,16));
1654  face[0] = stoi(sread.substr(48,16));
1655  face[1] = stoi(sread.substr(64,16));
1656  face[2] = stoi(sread.substr(80,16));
1657  faces.push_back(face);
1658  facesID.push_back(iface);
1659  PIDS.push_back(pid);
1660  std::getline(is,sread);
1661  ssub = trim(sread.substr(0,8));
1662  }
1663  else if(ssub == "CQUAD4"){
1664  face.resize(4);
1665  iface = stoi(sread.substr(8,8));
1666  pid = stoi(sread.substr(16,8));
1667  face[0] = stoi(sread.substr(24,8));
1668  face[1] = stoi(sread.substr(32,8));
1669  face[2] = stoi(sread.substr(40,8));
1670  face[3] = stoi(sread.substr(48,8));
1671  faces.push_back(face);
1672  facesID.push_back(iface);
1673  PIDS.push_back(pid);
1674  std::getline(is,sread);
1675  ssub = trim(sread.substr(0,8));
1676  }
1677  else if(ssub == "CQUAD4*"){
1678  face.resize(4);
1679  iface = stoi(sread.substr(16,16));
1680  pid = stoi(sread.substr(32,16));
1681  face[0] = stoi(sread.substr(48,16));
1682  face[1] = stoi(sread.substr(64,16));
1683  face[2] = stoi(sread.substr(80,16));
1684  face[3] = stoi(sread.substr(96,16));
1685  faces.push_back(face);
1686  facesID.push_back(iface);
1687  PIDS.push_back(pid);
1688  std::getline(is,sread);
1689  ssub = trim(sread.substr(0,8));
1690  }
1691  else if(ssub == "CBAR"){
1692  face.resize(2);
1693  iface = stoi(sread.substr(8,8));
1694  pid = stoi(sread.substr(16,8));
1695  face[0] = stoi(sread.substr(24,8));
1696  face[1] = stoi(sread.substr(32,8));
1697  faces.push_back(face);
1698  facesID.push_back(iface);
1699  PIDS.push_back(pid);
1700  std::getline(is,sread);
1701  ssub = trim(sread.substr(0,8));
1702  }
1703  else if(ssub == "RBE3"){
1704 
1705  long ID;
1706  std::vector<long> conn;
1707  long PID;
1708  std::string components;
1709 
1710  std::vector<std::string> records;
1711  bool toexit = false;
1712  while (!toexit){
1713  appendLineRecords(sread, 8, records);
1714  getline(is,sread);
1715  ssub = sread.substr(0,8);
1716  if ((ssub != " " && ssub[0] != '+'))
1717  toexit = true;
1718  }
1719 
1720  absorbRBE3(records, ID, PID, conn, components);
1721 
1722  //If surface elements build polygon
1723  std::size_t nv = conn.size();
1724 
1725  int ispolygon = int(nv > 4);
1726  face.resize(nv+ispolygon);
1727  face[0] = nv;
1728  for (std::size_t i=0; i<nv; i++){
1729  face[i+ispolygon] = conn[i];
1730  }
1731  faces.push_back(face);
1732  facesID.push_back(ID);
1733  PIDS.push_back(PID);
1734 
1735  }
1736  else if(ssub == "RBE2"){
1737 
1738  long ID;
1739  std::vector<long> conn;
1740  long PID;
1741  std::string components;
1742 
1743  std::vector<std::string> records;
1744  bool toexit = false;
1745  while (!toexit){
1746  appendLineRecords(sread, 8, records);
1747  getline(is,sread);
1748  ssub = sread.substr(0,8);
1749  if ((ssub != " " && ssub[0] != '+')){
1750  toexit = true;
1751  }
1752  }
1753 
1754  absorbRBE2(records, ID, PID, conn, components);
1755 
1756  // build polygon
1757  std::size_t nv = conn.size();
1758 
1759  int ispolygon = int(nv > 4);
1760  face.resize(nv+ispolygon);
1761  face[0] = nv;
1762  for (std::size_t i=0; i<nv; i++){
1763  face[i+ispolygon] = conn[i];
1764  }
1765  faces.push_back(face);
1766  facesID.push_back(ID);
1767  PIDS.push_back(PID);
1768 
1769  }
1770 
1771  }
1772  is.close();
1773 
1774 }
1775 
1780 std::string
1781 NastranInterface::trim(std::string in){
1782 
1783  return bitpit::utils::string::trim(in);
1784 
1785 /*
1786  * Old implementation for CentOS 5 system
1787 
1788  std::stringstream out;
1789  out << in;
1790  out >> in;
1791  return in;
1792 */
1793 
1794 }
1795 
1800 std::string
1802  int pos = in.find_last_of("-");
1803  if (pos<(int)in.size() && pos > 0){
1804  in.insert(pos, "E");
1805  }
1806  else{
1807  pos = in.find_last_of("+");
1808  if (pos<(int)in.size() && pos > 0){
1809  in.insert(pos, "E");
1810  }
1811  }
1812  return in;
1813 }
1814 
1821 void
1822 NastranInterface::appendLineRecords(std::string & sread, std::size_t recordlength, std::vector<std::string> & records)
1823 {
1824  std::size_t readlength = sread.size();
1825  std::size_t readpos = 0;
1826  while (readpos < readlength){
1827  std::string record = sread.substr(readpos, recordlength);
1828  record = bitpit::utils::string::trim(record);
1829  // Do not append empty records or blank spaces or new line tag (ANSA format, starting with character '+')
1830  if (!record.empty() && record != " " && record[0] != '+'){
1831  records.push_back(record);
1832  }
1833  readpos += recordlength;
1834  }
1835 }
1836 
1845 void
1846 NastranInterface::absorbRBE3(std::vector<std::string> & records, long & ID, long & PID, std::vector<long> & connectivity, std::string & components)
1847 {
1848  connectivity.clear();
1849  ID = std::stoi(records[1]);
1850  records[2] = bitpit::utils::string::trim(records[2]);
1851  if(!records[2].empty()){
1852  PID = std::stoi(records[2]);
1853  }
1854  else{
1855  PID = 0;
1856  }
1857  components = records[3];
1858  std::size_t startpos = 4;
1859  std::size_t endpos = records.size();
1860  for (std::size_t pos = startpos; pos < endpos; pos++){
1861  // If it is not integer it is the string UM or the weight factor
1862  // It can be even a new line tag (ANSA format)
1863  if(!isInteger(records[pos]) || records[pos].empty()){
1864  if(records[pos] == "UM" || records[pos].empty()){
1865  return;
1866  }
1867  else{
1868  // If not integer it is weight factor
1869  if(!isInteger(records[pos])){
1870  if (pos < endpos - 1 && records[pos][0] != '+'){
1871  // Skip even components numbers after weight factor
1872  pos++;
1873  }
1874  }
1875  }
1876  }
1877  else{
1878  long item = std::stoi(records[pos]);
1879  if (!std::count(connectivity.begin(), connectivity.end(), item)){
1880  connectivity.push_back(item);
1881  }
1882  }
1883  }
1884 }
1885 
1894 void
1895 NastranInterface::absorbRBE2(std::vector<std::string> & records, long & ID, long & PID, std::vector<long> & connectivity, std::string & components)
1896 {
1897  connectivity.clear();
1898  ID = std::stoi(records[1]);
1899  PID = std::stoi(records[2]);
1900  components = records[3];
1901  std::size_t startpos = 4;
1902  std::size_t endpos = records.size();
1903  for (std::size_t pos = startpos; pos < endpos; pos++){
1904  if(isInteger(records[pos])){
1905  long item = std::stoi(records[pos]);
1906  if (!std::count(connectivity.begin(), connectivity.end(), item))
1907  connectivity.push_back(item);
1908  }
1909  }
1910 }
1911 
1917 bool
1918 NastranInterface::isInteger(std::string & str){
1919  for (auto &val : str){
1920  if (!std::isdigit(val))
1921  return false;
1922  }
1923  return true;
1924 }
1925 
1931 bool
1932 NastranInterface::isEnabled(NastranElementType type){
1933  // If not in the map return false
1934  if (!m_enabled.count(type)){
1935  return false;
1936  }
1937  return m_enabled[type];
1938 }
1939 
1944 void
1945 NastranInterface::enable(NastranElementType type){
1946  m_enabled[type] = true;
1947 }
1948 
1953 void
1954 NastranInterface::disable(NastranElementType type){
1955  m_enabled[type] = false;
1956 }
1957 
1958 }
std::vector< livector1D > livector2D
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
void setClean(bool clean=true)
MimmoObject is the basic geometry container for mimmo library.
#define M_GEOM
void _setWrite(bool write=true)
void setGeometry(int type=1)
std::vector< darray3E > dvecarr3E
void setWriteFileType(FileType type)
void setBuildSkdTree(bool build)
Custom reader of unstructured grids from external files *.vtu.
void write(std::string &outputDir, std::string &surfaceName, dvecarr3E &points, livector1D &pointsID, livector2D &faces, livector1D &facesID, livector1D *PIDS=nullptr, std::unordered_set< long > *PIDSSET=nullptr)
std::vector< long > livector1D
void setReferencePID(long pid)
void setWriteDir(std::string dir)
void warningXML(bitpit::Logger *log, std::string name)
void setFileType(FileType type)
void setBuildKdTree(bool build)
void writeFace(std::string faceType, const livector1D &facePts, const long &nFace, std::ofstream &os, long PID)
BaseManipulation is the base class of any manipulation object of the library.
void setWriteFilename(std::string filename)
void writeKeyword(std::string key, std::ofstream &os)
bitpit::PiercedVector< bitpit::Vertex > * getVertices()
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
void writeValue(Type &value, std::ofstream &os)
void appendLineRecords(std::string &sread, std::size_t recordlength, std::vector< std::string > &records)
Custom writer of ASCII unstructured grids to external files *.vtu.
bool fileExist(const std::string &filename)
bool isInteger(std::string &str)
void writeFooter(std::ofstream &os, std::unordered_set< long > *PIDSSET=nullptr)
void setReadFilename(std::string filename)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
void setTolerance(double tol)
void swap(MimmoGeometry &x) noexcept
void setMultiSolidSTL(bool multi=true)
std::unordered_map< long int, long int > lilimap
MimmoGeometry is an executable block class wrapping(linking or internally instantiating) a Mimmo Obje...
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
void writeCoord(const darray3E &p, const long &pointI, std::ofstream &os)
MimmoSharedPointer< MimmoObject > m_geometry
std::string convertVertex(std::string in)
void absorbRBE3(std::vector< std::string > &records, long &ID, long &PID, std::vector< long > &connectivity, std::string &components)
bool isEnabled(NastranElementType type)
void read(std::string &inputDir, std::string &surfaceName, dvecarr3E &points, livector1D &pointsID, livector2D &faces, livector1D &facesID, livector1D &PIDS)
void setParallelRestore(bool parallelRestore=0)
Abstract class for custom ASCII writer/flusher of *.vtu mesh external files.
void setFilename(std::string filename)
void setCodex(bool binary=true)
MimmoGeometry(IOMode mode=IOMode::READ)
NastranInterface is an interface class for I/O handling of BDF bulk nastran format *....
void setFormatNAS(WFORMAT wform)
std::string trim(std::string in)
void setIOMode(IOMode mode)
void setGeometry(MimmoSharedPointer< MimmoObject > geometry)
void setPID(livector1D pids)
std::array< double, 3 > darray3E
const MimmoGeometry * getCopy()
void enable(NastranElementType type)
void absorbRBE2(std::vector< std::string > &records, long &ID, long &PID, std::vector< long > &connectivity, std::string &components)
void setReadFileType(FileType type)
bitpit::PiercedVector< bitpit::Cell > * getCells()
void disable(NastranElementType type)
MimmoSharedPointer< MimmoObject > getGeometry()
MimmoSharedPointer< MimmoObject > & getGeometryReference()
void write(const std::string &dir, const std::string &file, bitpit::VTKWriteMode mode=bitpit::VTKWriteMode::DEFAULT)
void swap(BaseManipulation &x) noexcept
void _setRead(bool read=true)
bool writeGeometry(dvecarr3E &points, livector1D &pointsID, livector2D &faces, livector1D &facesID, std::ofstream &os, livector1D *PIDS=nullptr)
MimmoGeometry & operator=(MimmoGeometry other)
void setDir(std::string dir)
void setReadDir(std::string dir)
std::map< NastranElementType, bool > m_enabled
Custom mesh/data absorber for unstructured grids given by external files *.vtu.