28#include <unordered_set>
72VTK::VTK(
const std::string &dir,
const std::string &name ):
85 if( st ==
"UInt32" || st ==
"UInt64"){
90 log::cout() <<
"Unsupported HeaderType " << st << std::endl ;
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 ;
243 field.setCodification( cod ) ;
254 for(
auto &field :
m_data)
255 field.setCodification( cod ) ;
265 const std::string &name = field.getName();
268 throw std::runtime_error(
"Not admissible to add geometry field with same name as user data " + name );
283 const std::string &name = field.
getName();
285 throw std::runtime_error(
"Not admissible to add user data with same name as geometry field " + name );
290 m_data[id] = std::move(field);
293 m_data.push_back(std::move(field));
310 throw std::runtime_error(
"Not admissible to add user data with same name as geometry field " + name);
332 std::vector<VTKField>::iterator fieldItr =
m_data.begin();
334 while( fieldItr !=
m_data.end()){
336 if( fieldItr->getName() == name){
337 fieldItr =
m_data.erase(fieldItr);
344 log::cout() <<
"did not find field for removing in VTK: " << name << std::endl;
355 if( field.getName() == name){
376 log::cout() <<
"did not find field for enabling: " << name << std::endl;
394 log::cout() <<
"did not find field for disabling: " << name << std::endl;
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();
539 assert(
id <
m_data.size());
541 return m_data.data() + id;
551 assert(
id <
m_data.size());
553 return m_data.data() + id;
590 for( std::size_t i = 0; i < fields.size(); ++i ) {
591 if( fields[i].
getName() == name ){
605 for(
auto & field :
m_data ){
606 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED) {
621 for(
auto & field :
m_data ){
622 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII) {
638 uint64_t HeaderByte(0) ;
641 HeaderByte =
sizeof(uint32_t) ;
645 HeaderByte =
sizeof(uint64_t) ;
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) ;
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) ;
663 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED ) {
664 field.setOffset( offset) ;
665 offset += HeaderByte + calcFieldSize(field) ;
677 for(
auto & field :
m_data ){
678 if( field.isEnabled() && !field.hasAllMetaData() ) {
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 ;
687 if( field.isEnabled() && !field.hasAllMetaData() ) {
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 ;
710 if( writeMode == VTKWriteMode::DEFAULT || writeMode == VTKWriteMode::NO_INCREMENT ){
726 if( writeMode == VTKWriteMode::NO_SERIES ){
728 }
else if( writeMode == VTKWriteMode::NO_INCREMENT ){
736 writeMetaInformation() ;
743 if( writeMode == VTKWriteMode::DEFAULT || writeMode == VTKWriteMode::NO_INCREMENT ){
745 }
else if( writeMode == VTKWriteMode::NO_SERIES ){
760 std::string oldName =
getName() ;
777 std::string oldName =
getName() ;
780 write(writeMode, time) ;
861 seriesFileHandler.
setName(seriesName) ;
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() +
"\"");
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();
883 dataSetFileHandler =
m_fh ;
886 dataSetFileHandler.
setName(outputName);
893 std::stringstream series;
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() +
"\"");
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);
905 if (collectionEnd || duplicateEntry) {
906 series <<
" <DataSet";
907 series <<
" timestep=\"" << time <<
"\"";
908 series <<
" file=\"" << dataSetFileHandler.
getPath() <<
"\"";
909 series <<
"/>" << std::endl;
912 if (!duplicateEntry) {
913 series << line << std::endl;
916 seriesFileStream.close();
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() +
"\"");
925 updatedSeriesFileStream << series.rdbuf();
926 updatedSeriesFileStream.close();
938 handler.
setName(collectionName) ;
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() +
"\"");
964 str.seekg(0, std::ios::beg);
972 std::fstream::pos_type position_insert = str.tellg();
975 for(
auto &field :
m_data ){
976 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII && field.getLocation() == VTKLocation::POINT ) {
977 str.seekg( position_insert);
980 str.seekg( field.getPosition() ) ;
984 position_insert = str.tellg();
986 if(position_insert==field.getPosition()){
987 log::cout() <<
"Error VTK: No data has been written for field " << field.
getName() << std::endl;
999 for(
auto &field :
m_data ){
1000 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII && field.getLocation() == VTKLocation::CELL ) {
1001 str.seekg( position_insert);
1004 str.seekg( field.getPosition() ) ;
1007 field.write( str ) ;
1008 position_insert = str.tellg();
1010 if(position_insert==field.getPosition()){
1011 log::cout() <<
"Error VTK: No data has been written for field " << field.
getName() << std::endl;
1023 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII ) {
1024 str.seekg( position_insert);
1027 str.seekg( field.getPosition() ) ;
1030 field.write( str ) ;
1031 position_insert = str.tellg();
1033 if(position_insert==field.getPosition()){
1034 log::cout() <<
"Error VTK: No data has been written for field " << field.
getName() << std::endl;
1046 str.seekg(0, std::ios::beg);
1054 std::fstream::pos_type position_before_write ;
1060 while( c_ !=
'_') str >> c_;
1065 for(
auto &field :
m_data ){
1066 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::POINT ) {
1068 uint32_t nbytes =
static_cast<uint32_t
>(calcFieldSize(field)) ;
1073 uint64_t nbytes = calcFieldSize(field) ;
1077 position_before_write = str.tellg();
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;
1086 for(
auto &field :
m_data ){
1087 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED && field.getLocation() == VTKLocation::CELL ) {
1090 uint32_t nbytes =
static_cast<uint32_t
>(calcFieldSize(field)) ;
1095 uint64_t nbytes = calcFieldSize(field) ;
1099 position_before_write = str.tellg();
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;
1111 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED ) {
1113 uint32_t nbytes =
static_cast<uint32_t
>(calcFieldSize(field)) ;
1118 uint64_t nbytes = calcFieldSize(field) ;
1122 position_before_write = str.tellg();
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;
1149 std::stringstream scalars, vectors ;
1151 for(
int j=0; j<2; j++){
1153 if( j==0 ) location = VTKLocation::POINT ;
1154 if( j==1 ) location = VTKLocation::CELL ;
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() <<
" " ;
1175 if( location == VTKLocation::POINT) {
1177 if( parallel ) str <<
"P" ;
1178 str <<
"PointData " ;
1181 else if( location == VTKLocation::CELL ) {
1183 if( parallel ) str <<
"P" ;
1184 str <<
"CellData " ;
1187 str <<
" Scalars=" << scalars.str()
1188 <<
" Vectors=" << vectors.str()
1189 <<
">" << std::endl;
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 );
1198 if( parallel ) str <<
"P" ;
1200 if( location == VTKLocation::POINT) str <<
"PointData> " << std::endl;
1201 if( location == VTKLocation::CELL) str <<
"CellData> " << std::endl;
1215 str <<
" </DataArray>" << std::endl ;
1227 str <<
" </PDataArray>" << std::endl ;
1236 readMetaInformation( );
1248 std::fstream::pos_type position_appended;
1254 str.open(
m_fh.
getPath( ), std::ios::in | std::ios::binary) ;
1258 bool foundAppendedSection =
false;
1259 while( !foundAppendedSection && getline(str, line) ){
1263 if( foundAppendedSection){
1265 while( c_ !=
'_') str >> c_;
1267 position_appended = str.tellg();
1271 for(
auto & field :
m_data){
1272 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED){
1274 str.seekg( position_appended) ;
1275 str.seekg( field.getOffset(), std::ios::cur) ;
1279#if BITPIT_ENABLE_DEBUG
1280 std::fstream::pos_type position_before = str.tellg();
1283 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
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;
1297 if( field.isEnabled() && field.getCodification() == VTKFormat::APPENDED){
1299 str.seekg( position_appended) ;
1300 str.seekg( field.getOffset(), std::ios::cur) ;
1304#if BITPIT_ENABLE_DEBUG
1305 std::fstream::pos_type position_before = str.tellg();
1308 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
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;
1322 str.seekg(0, std::ios::beg) ;
1328 for(
auto & field :
m_data ){
1329 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII){
1332 str.seekg( field.getPosition() ) ;
1333 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
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;
1345 if( field.isEnabled() && field.getCodification() == VTKFormat::ASCII){
1348 str.seekg( field.getPosition() ) ;
1350 field.read( str, calcFieldEntries(field), calcFieldComponents(field) ) ;
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;
1373 std::fstream::pos_type pos_ ;
1376 std::string locationString ;
1377 std::string line, loc;
1378 std::stringstream ss;
1387 std::unordered_set<std::string> unusedFields;
1389 unusedFields.insert(field.getName());
1393 for(
int i=0; i<2; i++){
1397 location = VTKLocation::POINT;
1398 locationString =
"Point" ;
1400 location = VTKLocation::CELL;
1401 locationString =
"Cell" ;
1407 ss <<
"</" << locationString <<
"Data>" ;
1411 if( ! getline( str, line) )
read =
false ;
1419 pos_ = str.tellg() ;
1442 if( unusedFields.count(ptemp->
getName()) > 0 ){
1443 unusedFields.erase(ptemp->
getName());
1449 if( ! getline( str, line) )
read = false ;
1456 for (
const std::string &fieldname : unusedFields) {
1472 while( getline(str, line) ){
1496 return "p" + getExtension();
Creates file names and checks status.
std::string getPath() const
void setParallel(bool p_)
const std::string & getDirectory() const
void setDirectory(const std::string &d_)
void setName(const std::string &n_)
const std::string & getName() const
void setAppendix(const std::string &a_)
std::string getName() const
The base class to be used to derive VTK streamers form.
VTKField handles geometry and data field information for the VTK format.
const std::string & getName() const
VTKFormat getCodification() const
std::fstream::pos_type getPosition() const
uint64_t getOffset() const
void setDataType(VTKDataType)
VTKFieldType getFieldType() const
VTKLocation getLocation() const
void setStreamer(VTKBaseStreamer &)
void setCodification(VTKFormat)
void setFieldType(VTKFieldType)
VTKDataType getDataType() const
void setPosition(std::fstream::pos_type)
void setLocation(VTKLocation)
A base class for VTK input output.
const VTKField * findGeomData(const std::string &name) const
virtual std::string getCollectionExtension() const
void setDirectory(const std::string &)
void setParallel(uint16_t, uint16_t)
std::size_t getDataCount() const
VTKField & addData(VTKField &&field)
std::vector< VTKField > m_geometry
void readDataHeader(std::fstream &)
void setNames(const std::string &, const std::string &)
int _findFieldIndex(const std::string &name, const std::vector< VTKField > &fields) const
void writeTimeSeries(double time) const
VTKField * _findData(const std::string &name)
VTKField * _findGeomData(const std::string &name)
const VTKField * findData(const std::string &name) const
std::vector< VTKField >::const_iterator getDataEnd() const
void disableData(const std::string &)
void setHeaderType(const std::string &)
void removeData(const std::string &)
std::string getName() const
const std::string & getHeaderType() const
bool readDataArray(std::fstream &, VTKField &) const
void setCounter(int c_=0)
void writeCollection() const
void enableData(const std::string &)
bool isASCIIActive() const
void setDataCodex(VTKFormat)
void setName(const std::string &)
void setGeomCodex(VTKFormat)
std::vector< VTKField >::const_iterator getDataBegin() const
void writePDataArray(std::fstream &, const VTKField &) const
VTKField * getGeomData(std::size_t id)
bool hasData(const std::string &) const
std::vector< VTKField >::const_iterator getGeomDataBegin() const
VTKField * getData(std::size_t id)
void setGeomData(VTKField &&field)
std::vector< VTKField >::const_iterator getGeomDataEnd() const
void calcAppendedOffsets()
void writeDataHeader(std::fstream &, bool parallel=false) const
bool isAppendedActive() const
std::size_t getGeomDataCount() const
void writeDataArray(std::fstream &, const VTKField &) const
std::vector< VTKField > m_data
FileHandler createCollectionHandler(const std::string &collectionName) const
std::string getDirectory() const
void write(VTKWriteMode writeMode, double time)
std::vector< std::string > getFieldNames(const std::vector< VTKField > &fields) const
bool keywordInString(const std::string &line, const std::string &key)
void copyUntilEOFInString(std::fstream &str, char *&buffer, int &length)
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)
std::string convertDataArrayToString(const VTKField &)
std::string convertPDataArrayToString(const VTKField &)
bool convertStringToDataArray(const std::string &, VTKField &)