430 lines
12 KiB
C++
430 lines
12 KiB
C++
/*------------------------------- phasicFlow ---------------------------------
|
|
O C enter of
|
|
O O E ngineering and
|
|
O O M ultiscale modeling of
|
|
OOOOOOO F luid flow
|
|
------------------------------------------------------------------------------
|
|
Copyright (C): www.cemf.ir
|
|
email: hamid.r.norouzi AT gmail.com
|
|
------------------------------------------------------------------------------
|
|
Licence:
|
|
This file is part of phasicFlow code. It is a free software for simulating
|
|
granular and multiphase flows. You can redistribute it and/or modify it under
|
|
the terms of GNU General Public License v3 or any other later versions.
|
|
|
|
phasicFlow is distributed to help others in their research in the field of
|
|
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
#include <regex>
|
|
|
|
#include "vtkFile.hpp"
|
|
#include "vocabs.hpp"
|
|
#include "pointFieldToVTK.hpp"
|
|
|
|
|
|
bool pFlow::PFtoVTK::convertTimeFolderPointFields(
|
|
systemControl &control,
|
|
const fileSystem &destPath,
|
|
const word &bName,
|
|
word& filename)
|
|
{
|
|
|
|
fileSystem timeFolder = control.time().path();
|
|
// check if pointStructure exist in this folder
|
|
IOfileHeader pStructHeader(
|
|
objectFile(
|
|
pointStructureFile__,
|
|
timeFolder,
|
|
objectFile::READ_ALWAYS,
|
|
objectFile::WRITE_ALWAYS));
|
|
|
|
if (!pStructHeader.headerOk(true))
|
|
{
|
|
output << yellowColor << "Time folder " <<
|
|
control.time().path() << " does not contain any pStructure data file."<<
|
|
" Skipping this folder . . ."<< defaultColor << nl;
|
|
return true;
|
|
}
|
|
|
|
vtkFile vtk(destPath, bName, control.time().currentTime(), bindaryOutput__);
|
|
|
|
if (!vtk)
|
|
return false;
|
|
|
|
filename = vtk.fileName().wordPath();
|
|
|
|
REPORT(1);
|
|
auto pStruct = pointStructure(control, 0.0005);
|
|
|
|
// get a list of files in this timeFolder;
|
|
|
|
auto posVec = pStruct.pointPositionHost();
|
|
auto *pos = posVec.data();
|
|
|
|
REPORT(2) << ">>> Writing pointStructure to vtk file with " <<
|
|
Yellow_Text(pStruct.numActive())<<
|
|
" active particles" << END_REPORT;
|
|
|
|
addUndstrcuturedGridField(
|
|
vtk(),
|
|
pos,
|
|
pStruct.numActive());
|
|
|
|
auto fileList = containingFiles(timeFolder);
|
|
|
|
for (const auto &file : fileList)
|
|
{
|
|
|
|
IOfileHeader fieldHeader(
|
|
objectFile(
|
|
file.fileName(),
|
|
file.dirPath(),
|
|
objectFile::READ_ALWAYS,
|
|
objectFile::WRITE_ALWAYS));
|
|
|
|
if (fieldHeader.headerOk(true))
|
|
{
|
|
// 64-bit intergers are not supported for convertion
|
|
if(
|
|
convertRealx3TypePointField(vtk(), fieldHeader, pStruct) ||
|
|
convertRealTypePointField(vtk(), fieldHeader, pStruct) ||
|
|
convertIntPointField<uint32>(vtk(), fieldHeader, pStruct) ||
|
|
//convertIntPointField<uint64>(vtk(), fieldHeader, pStruct) ||
|
|
convertIntPointField<int32>(vtk(), fieldHeader, pStruct) ||
|
|
//convertIntPointField<int64>(vtk(), fieldHeader, pStruct)||
|
|
fieldHeader.objectName() == pointStructureFile__ )
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
WARNING << " This object type, " <<
|
|
fieldHeader.objectType() << " is not supported" <<
|
|
END_WARNING;
|
|
}
|
|
}
|
|
output << endl;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::convertTimeFolderPointFieldsSelected(
|
|
systemControl &control,
|
|
const fileSystem &destPath,
|
|
const word &bName,
|
|
const wordVector &fieldsName,
|
|
bool mustExist,
|
|
word& filename)
|
|
{
|
|
fileSystem timeFolder = control.time().path();
|
|
// check if pointStructure exist in this folder
|
|
IOfileHeader pStructHeader(
|
|
objectFile(
|
|
pointStructureFile__,
|
|
timeFolder,
|
|
objectFile::READ_ALWAYS,
|
|
objectFile::WRITE_ALWAYS));
|
|
|
|
if (!pStructHeader.headerOk(true))
|
|
{
|
|
output << yellowColor << "Time folder " <<
|
|
control.time().path() <<
|
|
" does not contain any pStructure data file."<<
|
|
" Skipping this folder . . ."<< defaultColor << nl;
|
|
return true;
|
|
}
|
|
|
|
vtkFile vtk(destPath, bName, control.time().currentTime(), bindaryOutput__);
|
|
|
|
if (!vtk)
|
|
return false;
|
|
|
|
filename = vtk.fileName().wordPath();
|
|
|
|
REPORT(1);
|
|
auto pStruct = pointStructure(control, 0.0005);
|
|
|
|
// get a list of files in this timeFolder;
|
|
|
|
auto posVec = pStruct.pointPositionHost();
|
|
auto *pos = posVec.data();
|
|
|
|
REPORT(2) << ">>> Writing pointStructure to vtk file with " <<
|
|
Yellow_Text(pStruct.numActive())
|
|
<< " active particles" << END_REPORT;
|
|
|
|
addUndstrcuturedGridField(
|
|
vtk(),
|
|
pos,
|
|
pStruct.numActive());
|
|
|
|
auto fileList = containingFiles(timeFolder);
|
|
|
|
for (const auto &fname : fieldsName)
|
|
{
|
|
fileSystem fieldAddress = timeFolder + fname;
|
|
|
|
IOfileHeader fieldHeader(
|
|
objectFile(
|
|
fname,
|
|
timeFolder,
|
|
objectFile::READ_ALWAYS,
|
|
objectFile::WRITE_ALWAYS));
|
|
|
|
if (fieldHeader.headerOk(true))
|
|
{
|
|
if (
|
|
// 64-bit intergers are not supported for convertion
|
|
convertRealx3TypePointField(vtk(), fieldHeader, pStruct) ||
|
|
convertRealTypePointField(vtk(), fieldHeader, pStruct) ||
|
|
convertIntPointField<uint32>(vtk(), fieldHeader, pStruct) ||
|
|
// convertIntPointField<uint64>(vtk(), fieldHeader, pStruct) ||
|
|
convertIntPointField<int32>(vtk(), fieldHeader, pStruct) ||
|
|
//convertIntPointField<int64>(vtk(), fieldHeader, pStruct) ||
|
|
fieldHeader.objectName() == pointStructureFile__ )
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
|
|
WARNING << " This object type, " <<
|
|
fieldHeader.objectType() << " is not supported" <<
|
|
END_WARNING;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (mustExist)
|
|
{
|
|
fatalErrorInFunction << "Field " << fieldAddress <<
|
|
" does not exist." << endl;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
REPORT(2) << "Could not find " << Yellow_Text(fieldAddress) <<
|
|
". Skipping this field . . ." << END_REPORT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool pFlow::PFtoVTK::addUndstrcuturedGridField(
|
|
Ostream &os,
|
|
realx3 *position,
|
|
uint32 numPoints)
|
|
{
|
|
|
|
os << "DATASET UNSTRUCTURED_GRID\n";
|
|
|
|
if (numPoints == 0)
|
|
return true;
|
|
|
|
os << "POINTS " << numPoints << " float"<<'\n';
|
|
if(bindaryOutput__)
|
|
{
|
|
for(uint32 i=0; i<numPoints; i++)
|
|
{
|
|
float x = byteSwaper(static_cast<float>(position[i].x()));
|
|
float y = byteSwaper(static_cast<float>(position[i].y()));
|
|
float z = byteSwaper(static_cast<float>(position[i].z()));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&x), sizeof(x));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&y), sizeof(y));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&z), sizeof(z));
|
|
}
|
|
os<<'\n';
|
|
os << "CELLS " << numPoints << ' ' << 2 * numPoints<<'\n';
|
|
|
|
const int32 one_ro = byteSwaper(1);
|
|
for (int i = 0; i < numPoints; i++)
|
|
{
|
|
int pN = byteSwaper(i);
|
|
os.stdStream().write(reinterpret_cast<const char*>(&one_ro), sizeof(one_ro));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&pN), sizeof(pN));
|
|
}
|
|
os<<'\n';
|
|
os << "CELL_TYPES " << numPoints<<'\n';
|
|
for (int32 i = 0; i < numPoints; i++)
|
|
{
|
|
os.stdStream().write(reinterpret_cast<const char*>(&one_ro), sizeof(one_ro));
|
|
}
|
|
os<<'\n';
|
|
}
|
|
else
|
|
{
|
|
for (uint32 i = 0; i < numPoints; i++)
|
|
{
|
|
os << position[i].x() <<
|
|
' ' << position[i].y() <<
|
|
' ' << position[i].z() << '\n';
|
|
}
|
|
|
|
os << "CELLS " << numPoints << ' ' << 2 * numPoints << '\n';
|
|
for (uint32 i = 0; i < numPoints; i++)
|
|
{
|
|
os << 1 << ' ' << i << '\n';
|
|
}
|
|
|
|
os << "CELL_TYPES " << numPoints << '\n';
|
|
|
|
for (int32 i = 0; i < numPoints; i++)
|
|
{
|
|
os << 1 << '\n';
|
|
}
|
|
|
|
}
|
|
|
|
os << "POINT_DATA " << numPoints << endl;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::convertRealTypePointField(
|
|
Ostream &os,
|
|
const IOfileHeader &header,
|
|
pointStructure &pStruct)
|
|
{
|
|
word objectType = header.objectType();
|
|
|
|
if (!checkFieldType<real>(objectType))
|
|
return false;
|
|
|
|
REPORT(1);
|
|
auto field = realPointField_H(
|
|
header,
|
|
pStruct,
|
|
static_cast<real>(0));
|
|
|
|
real const *data = field.deviceViewAll().data();
|
|
|
|
REPORT(2) << ">>> Writing " << Green_Text(header.objectName()) <<
|
|
" field to vtk." << END_REPORT;
|
|
|
|
return addRealPointField(
|
|
os,
|
|
header.objectName(),
|
|
data,
|
|
pStruct.numActive());
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::convertRealx3TypePointField(
|
|
Ostream &os,
|
|
const IOfileHeader &header,
|
|
pointStructure &pStruct)
|
|
{
|
|
word objectType = header.objectType();
|
|
|
|
if (!checkFieldType<realx3>(objectType))
|
|
return false;
|
|
|
|
REPORT(1);
|
|
auto field = realx3PointField_H(
|
|
header,
|
|
pStruct,
|
|
{0.0, 0.0, 0.0});
|
|
|
|
realx3 const *data = field.deviceViewAll().data();
|
|
|
|
REPORT(2) << ">>> Writing " << Green_Text(header.objectName()) <<
|
|
" field to vtk." << END_REPORT;
|
|
|
|
return addRealx3PointField(
|
|
os,
|
|
header.objectName(),
|
|
data,
|
|
pStruct.numActive());
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::addRealPointField(
|
|
Ostream &os,
|
|
const word &fieldName,
|
|
const real *field,
|
|
uint32 numData)
|
|
{
|
|
if (numData == 0)
|
|
return true;
|
|
|
|
os << "FIELD FieldData 1\n"
|
|
<< fieldName << " 1 " << numData << " float\n";
|
|
if(bindaryOutput__)
|
|
{
|
|
for (uint32 i = 0; i < numData; ++i)
|
|
{
|
|
float x = byteSwaper(static_cast<float>(field[i]));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&x), sizeof(x));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (uint32 i = 0; i < numData; ++i)
|
|
{
|
|
os << field[i] << '\n';
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::addRealx3PointField(
|
|
Ostream &os,
|
|
const word &fieldName,
|
|
const realx3 *field,
|
|
uint32 numData)
|
|
{
|
|
if (numData == 0)
|
|
return true;
|
|
|
|
os << "FIELD FieldData 1\n"
|
|
<< fieldName << " 3 " << numData << " float\n";
|
|
|
|
if(bindaryOutput__)
|
|
{
|
|
for(uint32 i=0; i<numData; i++)
|
|
{
|
|
float x = byteSwaper(static_cast<float>(field[i].x()));
|
|
float y = byteSwaper(static_cast<float>(field[i].y()));
|
|
float z = byteSwaper(static_cast<float>(field[i].z()));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&x), sizeof(x));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&y), sizeof(y));
|
|
os.stdStream().write(reinterpret_cast<const char*>(&z), sizeof(z));
|
|
}
|
|
os<<'\n';
|
|
}
|
|
else
|
|
{
|
|
for (uint32 i = 0; i < numData; ++i)
|
|
{
|
|
os << field[i].x() <<
|
|
' ' << field[i].y() <<
|
|
' ' << field[i].z() << '\n';
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
bool pFlow::PFtoVTK::regexCheck(const word &TYPENAME, const word &fieldType)
|
|
{
|
|
std::regex match("pointField\\<([A-Za-z1-9_]*)\\,([A-Za-z1-9_]*)\\>");
|
|
std::smatch search1;
|
|
std::smatch search2;
|
|
if (!std::regex_match(fieldType, search1, match))
|
|
return false;
|
|
if (!std::regex_match(TYPENAME, search2, match))
|
|
return false;
|
|
if (search1.size() != 3)
|
|
return false;
|
|
if (search1.size() != search2.size())
|
|
return false;
|
|
return search1[1] == search2[1];
|
|
} |