Loading...
Searching...
No Matches
VTK.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit 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 * bitpit 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 bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#include <cassert>
26#include <sstream>
27#include <string>
28#include <unordered_set>
29
30#include "VTK.hpp"
31
32#include "logger.hpp"
33
34namespace bitpit{
49
50 m_procs = 1;
51 m_rank = 0;
52
53 m_headerType = "UInt32" ;
54
55 m_fh.setDirectory( "." ) ;
56 m_fh.setSeries( false ) ;
57 m_fh.setParallel( false ) ;
58
59 m_geomCodex = VTKFormat::APPENDED ;
60 m_dataCodex = VTKFormat::APPENDED ;
61
62 m_cells = 0;
63 m_points= 0;
64
65}
66
72VTK::VTK(const std::string &dir, const std::string &name ):
73 VTK(){
74
75 setNames(dir, name) ;
76
77}
78
83void VTK::setHeaderType(const std::string &st){
84
85 if( st == "UInt32" || st == "UInt64"){
86 m_headerType = st ;
87 }
88
89 else{
90 log::cout() << "Unsupported HeaderType " << st << std::endl ;
91 }
92
93}
94
99const std::string & VTK::getHeaderType( ) const{
100 return m_headerType ;
101}
102
108void VTK::setNames( const std::string &dir, const std::string &name ){
109
110 setDirectory(dir);
111 setName(name);
112
113}
114
119void VTK::setName( const std::string &name ){
120
121 m_fh.setName(name);
122
123}
124
129void VTK::setDirectory( const std::string &dir ){
130
131 m_fh.setDirectory(dir);
132
133}
134
139std::string VTK::getName() const {
140
141 return m_fh.getName();
142}
143
148std::string VTK::getDirectory() const {
149
150 return m_fh.getDirectory();
151}
152
157void VTK::setCounter( int counter){
158
159 m_fh.setSeries(true) ;
160 m_fh.setCounter(counter) ;
161
162}
163
169
170 if (!m_fh.isSeries()) {
171 setCounter(0);
172 } else {
174 }
175
176}
177
183
184 int counter = getCounter() ;
185 m_fh.setSeries(false) ;
186
187 return counter;
188}
189
194int VTK::getCounter( ) const{
195
196 return m_fh.getCounter( ) ;
197
198}
199
205void VTK::setParallel( uint16_t procs, uint16_t rank){
206
207 if( procs < 1 ) log::cout() << " Numer of processes must be greater than 0" << std::endl ;
208 if( rank >= procs) log::cout() << " m_rankess is not in valid range " << std::endl ;
209
210 m_procs = procs;
211 m_rank = rank;
212
213 if(m_procs == 0) {
214 m_fh.setParallel(false) ;
215 }
216
217 else {
218 m_fh.setParallel(true) ;
219 m_fh.setBlock( rank ) ;
220 }
221
222}
223
229
230 setGeomCodex( cod) ;
231 setDataCodex( cod) ;
232
233}
234
240
241 m_geomCodex = cod ;
242 for( auto &field : m_geometry)
243 field.setCodification( cod ) ;
244
245}
246
252
253 m_dataCodex = cod ;
254 for( auto &field : m_data)
255 field.setCodification( cod ) ;
256
257}
258
264
265 const std::string &name = field.getName();
266 int id = _findFieldIndex( name, m_geometry ) ;
267 if( id < 0 ){
268 throw std::runtime_error("Not admissible to add geometry field with same name as user data " + name );
269 }
270
271 m_geometry[id] = std::move(field);
272
273}
274
282
283 const std::string &name = field.getName();
284 if( findGeomData(name) ){
285 throw std::runtime_error("Not admissible to add user data with same name as geometry field " + name );
286 }
287
288 int id = _findFieldIndex( name, m_data ) ;
289 if (id >= 0) {
290 m_data[id] = std::move(field);
291 } else {
292 id = m_data.size();
293 m_data.push_back(std::move(field));
294 }
295
296 return m_data[id] ;
297
298}
299
307VTKField& VTK::addData( const std::string &name, VTKBaseStreamer* streamer ){
308
309 if( findGeomData(name) ){
310 throw std::runtime_error("Not admissible to add user data with same name as geometry field " + name);
311 }
312
313 VTKField *ptr = _findData( name ) ;
314 if ( ! ptr ) {
315 m_data.push_back( VTKField( name ) ) ;
316 ptr = &(m_data.back()) ;
317 }
318
320 ptr->setStreamer(*streamer) ;
321
322 return *ptr ;
323
324}
325
330void VTK::removeData( const std::string &name ){
331
332 std::vector<VTKField>::iterator fieldItr = m_data.begin();
333
334 while( fieldItr != m_data.end()){
335
336 if( fieldItr->getName() == name){
337 fieldItr = m_data.erase(fieldItr);
338 return;
339 } else {
340 ++fieldItr;
342 }
343
344 log::cout() << "did not find field for removing in VTK: " << name << std::endl;
345
346}
347
352bool VTK::hasData( const std::string &name ) const {
353
354 for ( const VTKField &field : m_data ) {
355 if( field.getName() == name){
356 return true;
357 }
358 }
359
360 return false;
361
362}
363
368void VTK::enableData( const std::string &name ){
369
370 VTKField *field = _findData(name);
371
372 if( field ) {
373 field->enable() ;
374
375 } else{
376 log::cout() << "did not find field for enabling: " << name << std::endl;
377 }
378
379
380}
381
386void VTK::disableData( const std::string &name ){
387
388 VTKField *field = _findData(name);
389
390 if( field ) {
391 field->disable() ;
392
393 } else{
394 log::cout() << "did not find field for disabling: " << name << std::endl;
395 }
396
397}
398
403std::vector<std::string> VTK::getFieldNames( const std::vector<VTKField> &fields ) const {
404
405 std::size_t nFields = fields.size();
406 std::vector<std::string> names(nFields);
407 for (std::size_t i = 0; i < nFields; ++i) {
408 names[i] = fields[i].getName();
409 }
410
411 return names;
412}
413
418std::vector<VTKField>::const_iterator VTK::getDataBegin( ) const {
419
420 return m_data.cbegin();
421}
422
427std::vector<VTKField>::const_iterator VTK::getDataEnd( ) const {
428
429 return m_data.cend();
430}
431
436std::vector<VTKField>::const_iterator VTK::getGeomDataBegin( ) const {
437
438 return m_geometry.cbegin();
439}
440
445std::vector<VTKField>::const_iterator VTK::getGeomDataEnd( ) const {
446
447 return m_geometry.cend();
448}
449
454std::size_t VTK::getDataCount( ) const {
455
456 return m_data.size();
457}
458
463std::size_t VTK::getGeomDataCount( ) const {
464
465 return m_geometry.size();
466}
467
474const VTKField * VTK::findData( const std::string &name ) const {
475
476 int id = _findFieldIndex(name, m_data) ;
477 if (id >= 0) {
478 return getData(id);
479 } else {
480 return nullptr;
481 }
482}
483
490VTKField * VTK::_findData( const std::string &name ) {
491
492 int id = _findFieldIndex(name, m_data) ;
493 if (id >= 0) {
494 return getData(id);
495 } else {
496 return nullptr;
497 }
498}
499
506const VTKField * VTK::findGeomData( const std::string &name ) const {
507
508 int id = _findFieldIndex(name, m_geometry) ;
509 if (id >= 0) {
510 return getGeomData(id);
511 } else {
512 return nullptr;
513 }
514}
515
522VTKField * VTK::_findGeomData( const std::string &name ) {
523
524 int id = _findFieldIndex(name, m_geometry) ;
525 if (id >= 0) {
526 return getGeomData(id);
527 } else {
528 return nullptr;
529 }
530}
531
537const VTKField * VTK::getData( std::size_t id ) const {
538
539 assert(id < m_data.size());
540
541 return m_data.data() + id;
542}
543
549VTKField * VTK::getData( std::size_t id ) {
550
551 assert(id < m_data.size());
552
553 return m_data.data() + id;
554}
555
561const VTKField * VTK::getGeomData( std::size_t id ) const {
562
563 assert(id < m_geometry.size());
564
565 return m_geometry.data() + id;
566}
567
573VTKField * VTK::getGeomData( std::size_t id ) {
574
575 assert(id < m_geometry.size());
576
577 return m_geometry.data() + id;
578}
579
588int VTK::_findFieldIndex( const std::string &name, const std::vector<VTKField> &fields ) const {
589
590 for( std::size_t i = 0; i < fields.size(); ++i ) {
591 if( fields[i].getName() == name ){
592 return i ;
593 }
594 }
595
596 return -1 ;
597}
598
604
605 for( auto & field : m_data ){
606 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED) {
607 return true;
608 }
609 }
610
611 return false;
612
613}
614
619bool VTK::isASCIIActive() const {
620
621 for( auto & field : m_data ){
622 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII) {
623 return true;
624 }
625 }
626
627 return false;
628
629}
630
636
637 uint64_t offset(0) ;
638 uint64_t HeaderByte(0) ;
639
640 if( getHeaderType() == "UInt32"){
641 HeaderByte = sizeof(uint32_t) ;
642 }
643
644 else if( getHeaderType() == "UInt64") {
645 HeaderByte = sizeof(uint64_t) ;
646 }
647
648 for( auto & field : m_data ){
649 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::POINT ) {
650 field.setOffset( offset) ;
651 offset += HeaderByte + calcFieldSize(field) ;
652 }
653 }
654
655 for( auto & field : m_data ){
656 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::CELL) {
657 field.setOffset( offset) ;
658 offset += HeaderByte + calcFieldSize(field) ;
659 }
660 }
661
662 for( auto & field : m_geometry ){
663 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED ) {
664 field.setOffset( offset) ;
665 offset += HeaderByte + calcFieldSize(field) ;
666 }
667 }
668
669}
670
676
677 for( auto & field : m_data ){
678 if( field.isEnabled() && !field.hasAllMetaData() ) {
679 field.disable() ;
680#if BITPIT_ENABLE_DEBUG
681 log::cout() << "Data field " << field.getName() << " has not all metadata and has been disabled from reading/writing in VTK" << std::endl ;
682#endif
683 }
684 }
685
686 for( auto & field : m_geometry ){
687 if( field.isEnabled() && !field.hasAllMetaData() ) {
688 field.disable() ;
689#if BITPIT_ENABLE_DEBUG
690 log::cout() << "Geometry field " << field.getName() << " has not all metadata and has been disabled from reading/writing in VTK" << std::endl ;
691#endif
692 }
693 }
694
695}
696
704void VTK::write( VTKWriteMode writeMode, double time ){
705
706 // Write VTK file
707 write(writeMode);
708
709 // Write time series file
710 if( writeMode == VTKWriteMode::DEFAULT || writeMode == VTKWriteMode::NO_INCREMENT ){
711 writeTimeSeries(time);
712 }
713
714}
715
722void VTK::write( VTKWriteMode writeMode ){
723
724 // Initialize counter
725 int counter = getCounter();
726 if( writeMode == VTKWriteMode::NO_SERIES ){
727 unsetCounter() ;
728 } else if( writeMode == VTKWriteMode::NO_INCREMENT ){
729 setCounter(counter - 1) ;
730 }
731
732 // Write data
735
736 writeMetaInformation() ;
737 writeData() ;
738
739 // Write collection
741
742 // Update counter
743 if( writeMode == VTKWriteMode::DEFAULT || writeMode == VTKWriteMode::NO_INCREMENT ){
745 } else if( writeMode == VTKWriteMode::NO_SERIES ){
746 setCounter(counter) ;
747 }
748
749}
750
758void VTK::write( const std::string &name, VTKWriteMode writeMode ){
759
760 std::string oldName = getName() ;
761
762 setName(name) ;
763 write(writeMode) ;
764 setName(oldName) ;
765}
766
775void VTK::write( const std::string &name, VTKWriteMode writeMode, double time ){
776
777 std::string oldName = getName() ;
778
779 setName(name) ;
780 write(writeMode, time) ;
781 setName(oldName) ;
782
783}
784
789void VTK::writeCollection( ) const {
791}
792
799void VTK::writeCollection( const std::string &outputName ) const {
800 writeCollection(outputName, outputName) ;
801}
802
815void VTK::writeTimeSeries( double time ) const {
816 writeTimeSeries(getName(), getName(), time) ;
817}
818
832void VTK::writeTimeSeries( const std::string &outputName, double time ) const {
833 writeTimeSeries(outputName, outputName, time) ;
834}
835
850void VTK::writeTimeSeries( const std::string &outputName, const std::string &seriesName, double time ) const {
851
852 // Only one process should write the time series
853 if (m_rank != 0) {
854 return;
855 }
856
857 // Initialize series file handle
858 FileHandler seriesFileHandler = m_fh ;
859 seriesFileHandler.setSeries(false) ;
860 seriesFileHandler.setParallel(false) ;
861 seriesFileHandler.setName(seriesName) ;
862 seriesFileHandler.setAppendix("pvd") ;
863
864 // Initialize series
865 if (!seriesFileHandler.exists() || getCounter() == 0) {
866 std::fstream emptySeriesFileStream;
867 emptySeriesFileStream.open( seriesFileHandler.getPath(), std::ios::out | std::ios::trunc ) ;
868 if (!emptySeriesFileStream.is_open()) {
869 throw std::runtime_error("Cannot create file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
870 }
871
872 emptySeriesFileStream << "<?xml version=\"1.0\"?>" << std::endl;
873 emptySeriesFileStream << "<VTKFile type=\"Collection\" version=\"0.1\">" << std::endl;
874 emptySeriesFileStream << " <Collection>" << std::endl;
875 emptySeriesFileStream << " </Collection>" << std::endl;
876 emptySeriesFileStream << "</VTKFile>" << std::endl;
877 emptySeriesFileStream.close();
878 }
879
880 // Create updated series
881 FileHandler dataSetFileHandler;
882 if (m_procs <= 1) {
883 dataSetFileHandler = m_fh ;
884 dataSetFileHandler.setSeries(false) ;
885 dataSetFileHandler.setParallel(false) ;
886 dataSetFileHandler.setName(outputName);
887 } else {
888 dataSetFileHandler = createCollectionHandler(outputName) ;
889 }
890 dataSetFileHandler.setDirectory(".");
891
892 std::string line;
893 std::stringstream series;
894
895 std::fstream seriesFileStream;
896 seriesFileStream.open( seriesFileHandler.getPath( ), std::ios::in ) ;
897 if (!seriesFileStream.is_open()) {
898 throw std::runtime_error("Cannot read file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
899 }
900
901 while (std::getline(seriesFileStream, line)) {
902 bool duplicateEntry = (line.find("file=\"" + dataSetFileHandler.getPath() + "\"") != std::string::npos);
903 bool collectionEnd = (line.find("</Collection>") != std::string::npos);
904
905 if (collectionEnd || duplicateEntry) {
906 series << " <DataSet";
907 series << " timestep=\"" << time << "\"";
908 series << " file=\"" << dataSetFileHandler.getPath() << "\"";
909 series << "/>" << std::endl;
910 }
911
912 if (!duplicateEntry) {
913 series << line << std::endl;
914 }
915 }
916 seriesFileStream.close();
917
918 // Write updated series
919 std::ofstream updatedSeriesFileStream;
920 updatedSeriesFileStream.open( seriesFileHandler.getPath( )) ;
921 if (!updatedSeriesFileStream.is_open()) {
922 throw std::runtime_error("Cannot create file \"" + seriesFileHandler.getName() + "\"" + " inside the directory \"" + seriesFileHandler.getDirectory() + "\"");
923 }
924
925 updatedSeriesFileStream << series.rdbuf();
926 updatedSeriesFileStream.close();
927}
928
934FileHandler VTK::createCollectionHandler( const std::string &collectionName ) const {
935 FileHandler handler(m_fh) ;
936 handler.setSeries(false) ;
937 handler.setParallel(false) ;
938 handler.setName(collectionName) ;
940
941 return handler;
942}
943
948
949 int length;
950 char* buffer ;
951
952
953 //We need to open the file in binary mode in order for the seekg/tellg
954 //methods to work properly. ASCII mode does not guarantee a correct
955 //stream positioning, because of automatic jump of escape characters
956 // (e.g., "\n" on Unix or "\r\n" on Windows).
957 std::fstream str ;
958 str.open( m_fh.getPath( ), std::ios::in | std::ios::out | std::ios::binary ) ;
959 if (!str.is_open()) {
960 throw std::runtime_error("Cannot create file \"" + m_fh.getName() + "\"" + " inside the directory \"" + m_fh.getDirectory() + "\"");
961 }
962
963 //Position the input stream at the beginning
964 str.seekg(0, std::ios::beg);
965
966 if (isASCIIActive()) { // Write Ascii
967 //
968 // It is fine to write ASCII on a binary opened file because the method
969 // genericIO::flushBinary is basically a reinterpret_cast of chars into
970 // chars and ensures consistent results.
971
972 std::fstream::pos_type position_insert = str.tellg();
973
974 //Writing first point data then cell data
975 for( auto &field : m_data ){
976 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII && field.getLocation() == VTKLocation::POINT ) {
977 str.seekg( position_insert);
978 readDataArray( str, field ) ;
979
980 str.seekg( field.getPosition() ) ;
981 genericIO::copyUntilEOFInString( str, buffer, length );
982
983 field.write( str ) ;
984 position_insert = str.tellg();
985
986 if(position_insert==field.getPosition()){
987 log::cout() << "Error VTK: No data has been written for field " << field.getName() << std::endl;
988 assert(false);
989 }
990
991 str << std::endl ;
992 genericIO::flushBINARY( str, buffer, length) ;
993
994 delete [] buffer ;
995
996 }
997 }
998
999 for( auto &field : m_data ){
1000 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII && field.getLocation() == VTKLocation::CELL ) {
1001 str.seekg( position_insert);
1002 readDataArray( str, field ) ;
1003
1004 str.seekg( field.getPosition() ) ;
1005 genericIO::copyUntilEOFInString( str, buffer, length );
1006
1007 field.write( str ) ;
1008 position_insert = str.tellg();
1009
1010 if(position_insert==field.getPosition()){
1011 log::cout() << "Error VTK: No data has been written for field " << field.getName() << std::endl;
1012 assert(false);
1013 }
1014
1015 str << std::endl ;
1016 genericIO::flushBINARY( str, buffer, length) ;
1017
1018 delete [] buffer ;
1019 }
1020 }
1021
1022 for( auto &field : m_geometry ){
1023 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII ) {
1024 str.seekg( position_insert);
1025 readDataArray( str, field ) ;
1026
1027 str.seekg( field.getPosition() ) ;
1028 genericIO::copyUntilEOFInString( str, buffer, length );
1029
1030 field.write( str ) ;
1031 position_insert = str.tellg();
1032
1033 if(position_insert==field.getPosition()){
1034 log::cout() << "Error VTK: No data has been written for field " << field.getName() << std::endl;
1035 assert(false);
1036 }
1037
1038 str << std::endl ;
1039 genericIO::flushBINARY( str, buffer, length) ;
1040
1041 delete [] buffer ;
1042 }
1043 }
1044
1045 // Position the stream at the beginning of the stream
1046 str.seekg(0, std::ios::beg);
1047
1048 }
1049
1050 if (isAppendedActive()) { // Write Appended
1051
1052 char c_;
1053 std::string line ;
1054 std::fstream::pos_type position_before_write ;
1055
1056 //Go to the initial position of the appended section
1057 while( getline(str, line) && (! bitpit::utils::string::keywordInString( line, "<AppendedData")) ){}
1058
1059 str >> c_;
1060 while( c_ != '_') str >> c_;
1061
1062 genericIO::copyUntilEOFInString( str, buffer, length );
1063
1064 //Writing first point data then cell data
1065 for( auto &field : m_data ){
1066 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::POINT ) {
1067 if( getHeaderType() == "UInt32"){
1068 uint32_t nbytes = static_cast<uint32_t>(calcFieldSize(field)) ;
1069 genericIO::flushBINARY(str, nbytes) ;
1070 }
1071
1072 else{
1073 uint64_t nbytes = calcFieldSize(field) ;
1074 genericIO::flushBINARY(str, nbytes) ;
1075 }
1076
1077 position_before_write = str.tellg();
1078 field.write(str) ;
1079 if( (uint64_t) str.tellg()-position_before_write != calcFieldSize(field) ){
1080 log::cout() << "Error VTK: Data written do not corrispond to size of field " << field.getName() << std::endl;
1081 assert(false);
1082 }
1083 }
1084 }
1085
1086 for( auto &field : m_data ){
1087 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::CELL ) {
1088
1089 if( getHeaderType() == "UInt32"){
1090 uint32_t nbytes = static_cast<uint32_t>(calcFieldSize(field)) ;
1091 genericIO::flushBINARY(str, nbytes) ;
1092 }
1093
1094 else{
1095 uint64_t nbytes = calcFieldSize(field) ;
1096 genericIO::flushBINARY(str, nbytes) ;
1097 }
1098
1099 position_before_write = str.tellg();
1100 field.write(str) ;
1101 if( (uint64_t) str.tellg()-position_before_write != calcFieldSize(field) ){
1102 log::cout() << "Error VTK: Data written do not corrispond to size of field " << field.getName() << std::endl;
1103 assert(false);
1104 }
1105
1106 }
1107 }
1108
1109 //Writing Geometry Data
1110 for( auto &field : m_geometry ){
1111 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED ) {
1112 if( getHeaderType() == "UInt32"){
1113 uint32_t nbytes = static_cast<uint32_t>(calcFieldSize(field)) ;
1114 genericIO::flushBINARY(str, nbytes) ;
1115 }
1116
1117 else{
1118 uint64_t nbytes = calcFieldSize(field) ;
1119 genericIO::flushBINARY(str, nbytes) ;
1120 }
1121
1122 position_before_write = str.tellg();
1123 field.write(str) ;
1124 if( (uint64_t) str.tellg()-position_before_write != calcFieldSize(field) ){
1125 log::cout() << "Error VTK: Data written do not corrispond to size of field " << field.getName() << std::endl;
1126 assert(false);
1127 }
1128 }
1129 }
1130
1131 genericIO::flushBINARY( str, buffer, length) ;
1132
1133 delete [] buffer ;
1134 }
1135
1136 // Closing Appended Section
1137 str.close();
1138
1139}
1140
1146void VTK::writeDataHeader( std::fstream &str, bool parallel ) const {
1147
1148 VTKLocation location ;
1149 std::stringstream scalars, vectors ;
1150
1151 for( int j=0; j<2; j++){
1152
1153 if( j==0 ) location = VTKLocation::POINT ;
1154 if( j==1 ) location = VTKLocation::CELL ;
1155
1156 scalars.str("");
1157 vectors.str("");
1158
1159 //Creating Scalar and Vector Lists
1160 scalars << "\"" ;
1161 vectors << "\"" ;
1162
1163 for( auto &field : m_data ){
1164 if( field.isEnabled() && field.getLocation() == location){
1165 if( field.getFieldType() == VTKFieldType::SCALAR ) scalars << field.getName() << " " ;
1166 else if( field.getFieldType() == VTKFieldType::VECTOR ) vectors << field.getName() << " " ;
1167 else if( field.getFieldType() == VTKFieldType::TENSOR ) vectors << field.getName() << " " ;
1168 }
1169
1170 }
1171
1172 scalars << "\"" ;
1173 vectors << "\"" ;
1174
1175 if( location == VTKLocation::POINT) {
1176 str << " <" ;
1177 if( parallel ) str << "P" ;
1178 str << "PointData " ;
1179 }
1180
1181 else if( location == VTKLocation::CELL ) {
1182 str << " <" ;
1183 if( parallel ) str << "P" ;
1184 str << "CellData " ;
1185 }
1186
1187 str << " Scalars=" << scalars.str()
1188 << " Vectors=" << vectors.str()
1189 << ">" << std::endl;
1190
1191 //Writing DataArray
1192 for( auto &field : m_data ){
1193 if( field.isEnabled() && field.getLocation() == location && !parallel) writeDataArray( str, field ) ;
1194 if( field.isEnabled() && field.getLocation() == location && parallel) writePDataArray( str, field );
1195 }
1196
1197 str << " </" ;
1198 if( parallel ) str << "P" ;
1199
1200 if( location == VTKLocation::POINT) str << "PointData> " << std::endl;
1201 if( location == VTKLocation::CELL) str << "CellData> " << std::endl;
1202
1203 }
1204
1205}
1206
1212void VTK::writeDataArray( std::fstream &str, const VTKField &field ) const {
1213
1214 str << vtk::convertDataArrayToString( field ) << std::endl ;
1215 str << " </DataArray>" << std::endl ;
1216
1217}
1218
1224void VTK::writePDataArray( std::fstream &str, const VTKField &field ) const {
1225
1226 str << vtk::convertPDataArrayToString( field ) << std::endl ;
1227 str << " </PDataArray>" << std::endl ;
1228
1229}
1230
1235
1236 readMetaInformation( );
1237 checkAllFields() ;
1238 readData( ) ;
1239
1240}
1241
1246
1247 std::fstream str ;
1248 std::fstream::pos_type position_appended;
1249 std::string line;
1250 char c_ ;
1251 uint32_t nbytes32 ;
1252 uint64_t nbytes64 ;
1253
1254 str.open( m_fh.getPath( ), std::ios::in | std::ios::binary) ;
1255
1256 //Read appended data
1257 //Go to the initial position of the appended section
1258 bool foundAppendedSection = false;
1259 while( !foundAppendedSection && getline(str, line) ){
1260 foundAppendedSection = bitpit::utils::string::keywordInString( line, "<AppendedData");
1261 }
1262
1263 if( foundAppendedSection){
1264 str >> c_;
1265 while( c_ != '_') str >> c_;
1266
1267 position_appended = str.tellg();
1268
1269
1270 //Read appended data
1271 for( auto & field : m_data){
1272 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED){
1273 str.clear();
1274 str.seekg( position_appended) ;
1275 str.seekg( field.getOffset(), std::ios::cur) ;
1276 if( m_headerType== "UInt32") genericIO::absorbBINARY( str, nbytes32 ) ;
1277 if( m_headerType== "UInt64") genericIO::absorbBINARY( str, nbytes64 ) ;
1278
1279#if BITPIT_ENABLE_DEBUG
1280 std::fstream::pos_type position_before = str.tellg();
1281#endif
1282
1283 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
1284
1285#if BITPIT_ENABLE_DEBUG
1286 if( uint64_t(str.tellg()-position_before) != calcFieldSize(field) ){
1287 log::cout() << "Warning VTK: Size of data read does not corrispond to size of field " << field.getName() << std::endl;
1288 log::cout() << "Found data chunk dimension of : "<< uint64_t(str.tellg()-position_before)<<" different from estimated field size : " <<calcFieldSize(field)<<std::endl;
1289 }
1290#endif
1291
1292 }
1293 }
1294
1295 //Read appended m_geometry
1296 for( auto & field : m_geometry ){
1297 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED){
1298 str.clear();
1299 str.seekg( position_appended) ;
1300 str.seekg( field.getOffset(), std::ios::cur) ;
1301 if( m_headerType== "UInt32") genericIO::absorbBINARY( str, nbytes32 ) ;
1302 if( m_headerType== "UInt64") genericIO::absorbBINARY( str, nbytes64 ) ;
1303
1304#if BITPIT_ENABLE_DEBUG
1305 std::fstream::pos_type position_before = str.tellg();
1306#endif
1307
1308 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
1309
1310#if BITPIT_ENABLE_DEBUG
1311 if( uint64_t(str.tellg()-position_before) != calcFieldSize(field) ){
1312 log::cout() << "Warning VTK: Size of data read does not corrispond to size of field " << field.getName() << std::endl;
1313 log::cout() << "Found data chunk dimension of : "<< uint64_t(str.tellg()-position_before)<<" different from estimated field size : " <<calcFieldSize(field)<<std::endl;
1314 }
1315#endif
1316 }
1317 }
1318
1319 //Leave the file opened in binary mode and reposition it to the start
1320 //to allow using seekg/tellg later.
1321 str.clear();
1322 str.seekg(0, std::ios::beg) ;
1323
1324 }
1325
1326
1327 //Read ascii data
1328 for( auto & field : m_data ){
1329 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII){
1330
1331 str.clear();
1332 str.seekg( field.getPosition() ) ;
1333 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
1334
1335#if BITPIT_ENABLE_DEBUG
1336 if(str.tellg()==field.getPosition()){
1337 log::cout() << "Warning VTK: No data have been read for field " << field.getName() << std::endl;
1338 }
1339#endif
1340 }
1341 }
1342
1343 //Read ascii geometry
1344 for( auto & field : m_geometry ){
1345 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII){
1346
1347 str.clear();
1348 str.seekg( field.getPosition() ) ;
1349
1350 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
1351
1352#if BITPIT_ENABLE_DEBUG
1353 if(str.tellg()==field.getPosition()){
1354 log::cout() << "Warning VTK: No data have been read for field " << field.getName() << std::endl;
1355 }
1356#endif
1357 }
1358 }
1359
1360 str.close();
1361
1362}
1363
1370void VTK::readDataHeader( std::fstream &str ){
1371
1372
1373 std::fstream::pos_type pos_ ;
1374
1375 VTKLocation location;
1376 std::string locationString ;
1377 std::string line, loc;
1378 std::stringstream ss;
1379
1380 bool read ;
1381
1382 VTKField temp ;
1383 VTKField* ptemp ;
1384
1385
1386 // Mark all fields as unused
1387 std::unordered_set<std::string> unusedFields;
1388 for (VTKField &field : m_data) {
1389 unusedFields.insert(field.getName());
1390 }
1391
1392 // Read header
1393 for( int i=0; i<2; i++){
1394
1395 ss.str("") ;
1396 if( i== 0) {
1397 location = VTKLocation::POINT;
1398 locationString = "Point" ;
1399 } else if( i== 1) {
1400 location = VTKLocation::CELL;
1401 locationString = "Cell" ;
1402 }
1403
1404
1405 temp.setLocation( location ) ;
1406
1407 ss << "</" << locationString << "Data>" ;
1408 loc = ss.str();
1409
1410 read= true ;
1411 if( ! getline( str, line) ) read = false ;
1412 if( bitpit::utils::string::keywordInString( line, loc) ) read=false ;
1413
1414
1415 while( read ){
1416 if( vtk::convertStringToDataArray( line, temp ) ) {
1417
1418 if( temp.getCodification() == VTKFormat::ASCII) {
1419 pos_ = str.tellg() ;
1420 }
1421
1422 else{
1423 pos_ = 0 ;
1424 }
1425
1426 temp.setPosition( pos_ ) ;
1427
1428 ptemp = _findData( temp.getName() );
1429 if( !ptemp ) {
1430 m_data.push_back( VTKField( temp ) ) ;
1431 }
1432
1433 else{
1434 ptemp->setOffset( temp.getOffset() ) ;
1435 ptemp->setLocation( temp.getLocation() ) ;
1436 ptemp->setDataType( temp.getDataType() ) ;
1437 ptemp->setFieldType( temp.getFieldType() ) ;
1438 ptemp->setCodification( temp.getCodification() ) ;
1439 ptemp->setPosition( temp.getPosition() ) ;
1440
1441 // The field should not be marked as unused
1442 if( unusedFields.count(ptemp->getName()) > 0 ){
1443 unusedFields.erase(ptemp->getName());
1444 }
1445 }
1446
1447 }
1448
1449 if( ! getline( str, line) ) read = false ;
1450 if( bitpit::utils::string::keywordInString( line, loc) ) read=false ;
1451 }
1452
1453 }
1454
1455 // Disable all unused fields
1456 for (const std::string &fieldname : unusedFields) {
1457 VTKField *field = _findData(fieldname);
1458 assert(field);
1459 field->disable();
1460 }
1461}
1462
1468bool VTK::readDataArray( std::fstream &str, VTKField &field ) const {
1469
1470 std::string line ;
1471
1472 while( getline(str, line) ){
1473
1474 if( bitpit::utils::string::keywordInString( line, field.getName() ) ){
1475 if( vtk::convertStringToDataArray( line, field ) ){
1476
1477 if( field.getCodification() == VTKFormat::ASCII) {
1478 field.setPosition( str.tellg() ) ;
1479 }
1480
1481 return true ;
1482 }
1483 }
1484 }
1485
1486 return false ;
1487
1488}
1489
1495std::string VTK::getCollectionExtension() const {
1496 return "p" + getExtension();
1497}
1498
1499}
Creates file names and checks status.
std::string getPath() const
void setParallel(bool p_)
bool isSeries() const
const std::string & getDirectory() const
void setDirectory(const std::string &d_)
void setName(const std::string &n_)
bool exists() const
void setCounter(int c_)
const std::string & getName() const
void setBlock(int b_)
void setSeries(bool s_)
void setAppendix(const std::string &a_)
std::string getName() const
Definition logger.cpp:842
The base class to be used to derive VTK streamers form.
Definition VTK.hpp:209
VTKField handles geometry and data field information for the VTK format.
Definition VTK.hpp:247
const std::string & getName() const
Definition VTKField.cpp:167
VTKFormat getCodification() const
Definition VTKField.cpp:208
std::fstream::pos_type getPosition() const
Definition VTKField.cpp:225
uint64_t getOffset() const
Definition VTKField.cpp:216
void setDataType(VTKDataType)
Definition VTKField.cpp:97
VTKFieldType getFieldType() const
Definition VTKField.cpp:175
VTKLocation getLocation() const
Definition VTKField.cpp:200
void setStreamer(VTKBaseStreamer &)
Definition VTKField.cpp:145
void setCodification(VTKFormat)
Definition VTKField.cpp:113
void setFieldType(VTKFieldType)
Definition VTKField.cpp:121
VTKDataType getDataType() const
Definition VTKField.cpp:192
void setOffset(uint64_t)
Definition VTKField.cpp:137
void setPosition(std::fstream::pos_type)
Definition VTKField.cpp:129
void setLocation(VTKLocation)
Definition VTKField.cpp:105
A base class for VTK input output.
Definition VTK.hpp:298
const VTKField * findGeomData(const std::string &name) const
Definition VTK.cpp:506
virtual std::string getCollectionExtension() const
Definition VTK.cpp:1495
uint16_t m_rank
Definition VTK.hpp:305
uint64_t m_cells
Definition VTK.hpp:303
void setDirectory(const std::string &)
Definition VTK.cpp:129
void incrementCounter()
Definition VTK.cpp:168
void setParallel(uint16_t, uint16_t)
Definition VTK.cpp:205
std::size_t getDataCount() const
Definition VTK.cpp:454
VTKField & addData(VTKField &&field)
Definition VTK.cpp:281
std::vector< VTKField > m_geometry
Definition VTK.hpp:309
int getCounter() const
Definition VTK.cpp:194
void readDataHeader(std::fstream &)
Definition VTK.cpp:1370
void setNames(const std::string &, const std::string &)
Definition VTK.cpp:108
int _findFieldIndex(const std::string &name, const std::vector< VTKField > &fields) const
Definition VTK.cpp:588
void writeTimeSeries(double time) const
Definition VTK.cpp:815
VTKField * _findData(const std::string &name)
Definition VTK.cpp:490
FileHandler m_fh
Definition VTK.hpp:301
VTKField * _findGeomData(const std::string &name)
Definition VTK.cpp:522
const VTKField * findData(const std::string &name) const
Definition VTK.cpp:474
std::vector< VTKField >::const_iterator getDataEnd() const
Definition VTK.cpp:427
void read()
Definition VTK.cpp:1234
void disableData(const std::string &)
Definition VTK.cpp:386
void writeData()
Definition VTK.cpp:947
void readData()
Definition VTK.cpp:1245
void setHeaderType(const std::string &)
Definition VTK.cpp:83
void removeData(const std::string &)
Definition VTK.cpp:330
std::string getName() const
Definition VTK.cpp:139
const std::string & getHeaderType() const
Definition VTK.cpp:99
std::string m_headerType
Definition VTK.hpp:307
bool readDataArray(std::fstream &, VTKField &) const
Definition VTK.cpp:1468
void setCounter(int c_=0)
Definition VTK.cpp:157
void writeCollection() const
Definition VTK.cpp:789
void enableData(const std::string &)
Definition VTK.cpp:368
void setCodex(VTKFormat)
Definition VTK.cpp:228
bool isASCIIActive() const
Definition VTK.cpp:619
void setDataCodex(VTKFormat)
Definition VTK.cpp:251
void setName(const std::string &)
Definition VTK.cpp:119
void setGeomCodex(VTKFormat)
Definition VTK.cpp:239
VTKFormat m_dataCodex
Definition VTK.hpp:313
std::vector< VTKField >::const_iterator getDataBegin() const
Definition VTK.cpp:418
void writePDataArray(std::fstream &, const VTKField &) const
Definition VTK.cpp:1224
int unsetCounter()
Definition VTK.cpp:182
VTKField * getGeomData(std::size_t id)
Definition VTK.cpp:573
bool hasData(const std::string &) const
Definition VTK.cpp:352
std::vector< VTKField >::const_iterator getGeomDataBegin() const
Definition VTK.cpp:436
VTKField * getData(std::size_t id)
Definition VTK.cpp:549
uint16_t m_procs
Definition VTK.hpp:304
void setGeomData(VTKField &&field)
Definition VTK.cpp:263
std::vector< VTKField >::const_iterator getGeomDataEnd() const
Definition VTK.cpp:445
void calcAppendedOffsets()
Definition VTK.cpp:635
void writeDataHeader(std::fstream &, bool parallel=false) const
Definition VTK.cpp:1146
bool isAppendedActive() const
Definition VTK.cpp:603
std::size_t getGeomDataCount() const
Definition VTK.cpp:463
void writeDataArray(std::fstream &, const VTKField &) const
Definition VTK.cpp:1212
void checkAllFields()
Definition VTK.cpp:675
std::vector< VTKField > m_data
Definition VTK.hpp:312
FileHandler createCollectionHandler(const std::string &collectionName) const
Definition VTK.cpp:934
std::string getDirectory() const
Definition VTK.cpp:148
void write(VTKWriteMode writeMode, double time)
Definition VTK.cpp:704
uint64_t m_points
Definition VTK.hpp:302
std::vector< std::string > getFieldNames(const std::vector< VTKField > &fields) const
Definition VTK.cpp:403
VTKFormat m_geomCodex
Definition VTK.hpp:310
VTKFormat
Definition VTK.hpp:92
VTKWriteMode
Definition VTK.hpp:49
VTKLocation
Definition VTK.hpp:102
bool keywordInString(const std::string &line, const std::string &key)
void copyUntilEOFInString(std::fstream &str, char *&buffer, int &length)
Definition GenericIO.cpp:61
void absorbBINARY(std::fstream &str, data_T &data)
void flushBINARY(std::fstream &str, const data_T &data)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
Definition logger.cpp:1705
std::string convertDataArrayToString(const VTKField &)
Definition VTKUtils.cpp:144
std::string convertPDataArrayToString(const VTKField &)
Definition VTKUtils.cpp:171
bool convertStringToDataArray(const std::string &, VTKField &)
Definition VTKUtils.cpp:84
--- layout: doxygen_footer ---