/* This file is part of the OpenLB library
*
* Copyright (C) 2015 Mathias J. Krause, Benjamin Förster
* E-mail contact: info@openlb.net
* The most recent release of OpenLB can be downloaded at
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef VTI_READER_HH
#define VTI_READER_HH
#include
#include
#include
#include
#include
#include
#include
#include "geometry/cuboid2D.h"
#include "vtiReader.h"
#include "communication/heuristicLoadBalancer.h"
namespace olb {
//template< typename T, typename BaseType> class SuperData3D;
/* ------------------ BaseVTIreader -----------------*/
template
BaseVTIreader::BaseVTIreader( const std::string& fName, int dim,
std::string dName, const std::string class_name )
: clout(class_name), _dim(dim), _size(0), _origin(_dim, 0), _extent(_dim, 0),
_delta(0), _xmlReader(fName), _nCuboids(0)
{
// Read WholeExtent (2 * _dim ints) from XML File and calculate _extent
std::vector wholeExtend = readExtent(&_xmlReader["ImageData"], "WholeExtent");
_extent = getNbNodes(wholeExtend);
// Read _delta
std::stringstream stream_val_1(_xmlReader["ImageData"].getAttribute("Spacing"));
stream_val_1 >> _delta;
// Read _origin
std::stringstream stream_val_2(_xmlReader["ImageData"].getAttribute("Origin"));
for (auto& origin_i : _origin) {
stream_val_2 >> origin_i;
}
// Read _size and count cuboids (_nCuboids)
for ( auto& piece : _xmlReader["ImageData"] ) {
if (piece->getName() == "Piece") {
// Read _size from first dName PointData Tag
if ( _nCuboids == 0 ) {
for (auto &dataArray : (*piece)["PointData"]) {
if (dataArray->getAttribute("Name") == dName && dataArray->getName() == "DataArray") {
_size = this->getSize(*dataArray);
}
}
}
_nCuboids++;
}
}
}
template
void BaseVTIreader::printInfo()
{
clout << "Information on VTIreader Data:" << std::endl;
clout << "Origin: ";
for (auto& origin_i : _origin) {
clout << origin_i << " ";
}
clout << std::endl;
clout << "Extend: ";
for (auto& extend_i : _extent) {
clout << extend_i << " ";
}
clout << std::endl;
clout << "Spacing: " << _delta << std::endl;
}
template
std::vector BaseVTIreader::readExtent(const XMLreader* reader, std::string extAttrName)
{
// An extent is in the form of four (or six) integers "x0 x1 y0 y1 z0 z1"
// each representing a node number
std::stringstream extstr(reader->getAttribute(extAttrName));
std::vector extents;
int tmp;
for (int i = 0; i < 2 * _dim; ++i) {
extstr >> tmp;
extents.push_back(tmp);
}
return extents;
}
template
std::vector BaseVTIreader::getNbNodes(std::vector& extents)
{
// Convert 4D (or 6D) extents vector into 2D (3D) extent vector
std::vector nNodes;
for ( int i = 0; i < _dim; i++ ) {
nNodes.push_back(extents[ 2*i + 1 ] - extents[ 2* i ] + 1);
}
return nNodes;
}
template
int BaseVTIreader::getSize(const XMLreader& tag)
{
// read the NumberOfComponents-Attribute (VTI standard) and return as integer
int size = std::atoi((tag.getAttribute("NumberOfComponents")).c_str());
if (size == 0) {
clout << "VTI READER: NumberOfComponents zero or not given!" << std::endl;
clout << "EXAMPLE:
BaseVTIreader3D::BaseVTIreader3D( const std::string& fName, std::string dName,
const std::string class_name)
: BaseVTIreader(fName, 3, dName, class_name)
{
}
template
void BaseVTIreader3D::readCuboid(Cuboid3D& cuboid, XMLreader* piece)
{
if (piece->getName() == "Piece") {
std::vector extents = this->readExtent(piece, "Extent");
std::vector extent = this->getNbNodes(extents);
// int extents[i] is node number => multiply with _delta to get coordinate
cuboid.init(extents[0] * this->_delta,
extents[2] * this->_delta,
extents[4] * this->_delta,
this->_delta,
extent[0],
extent[1],
extent[2]);
}
}
template
bool BaseVTIreader3D::readBlockData(BlockData3D& blockData,
const XMLreader& pieceTag, const std::string dName)
{
/*** This is the main data reader method. All other methods use this one for accessing data ***/
// Calculate number of cells in each direction
std::vector extents = this->readExtent(&pieceTag, "Extent");
std::vector extent = this->getNbNodes(extents);
// Iterate through all tags and take the one with the given Name attribute
for (auto & dataArray : pieceTag["PointData"]) {
if (dataArray->getAttribute("Name") == dName && dataArray->getName() == "DataArray") {
std::string data_str;
if (dataArray->read(data_str)) {
std::stringstream stream_val(data_str);
// Careful: respect ordering in VTI File
for (int iz = 0; iz < blockData.getNz(); iz++) {
for (int iy = 0; iy < blockData.getNy(); iy++) {
for (int ix = 0; ix < blockData.getNx(); ix++) {
for (int iSize=0; iSize < blockData.getSize(); iSize++) {
BaseType tmp;
stream_val >> tmp;
// write tmp into blockData
blockData.get(ix, iy, iz, iSize) = tmp;
}
}
}
}
}
// set correct blockData Name (GenericF)
// blockData.getName() = dName;
return true;
}
}
return false;
}
/* ---------------- BlockVTIreader3D -------------------*/
template
BlockVTIreader3D::BlockVTIreader3D(const std::string& fName, const std::string dName )
: BaseVTIreader3D(fName, dName, "BlockVTIreader3D"),
_cuboid(this->_origin, this->_delta, this->_extent),
_blockData(_cuboid, this->_size)
{
// Only read the first tag in the XML file
this->readBlockData(_blockData, this->_xmlReader["ImageData"]["Piece"], dName);
}
template
BlockData3D& BlockVTIreader3D::getBlockData()
{
return _blockData;
}
template
Cuboid3D& BlockVTIreader3D::getCuboid()
{
return _cuboid;
}
/* --------------- SuperVTIreader3D ---------------------*/
template
SuperVTIreader3D::~SuperVTIreader3D()
{
delete _loadBalancer;
delete _cGeometry;
delete _superData;
}
template
SuperVTIreader3D::SuperVTIreader3D(const std::string& fName, const std::string dName )
: BaseVTIreader3D(fName, dName, "SuperVTIreader3D")
{
this->clout << "Start reading \"" << fName << "\"... "
<< "(" << this->_nCuboids << " cuboids)" << std::endl;
// Create CuboidGeometry
_cGeometry = new CuboidGeometry3D (this->_origin, this->_delta, this->_extent);
this->clout << "* Reading Cuboid Geometry..." << std::endl;
// Fill CuboidGeometry
readCuboidGeometry();
_cGeometry->printExtended();
// Create LoadBalancer
_loadBalancer = new HeuristicLoadBalancer (*_cGeometry);
// Create SuperData (allocation of the data, this->_size is already known!)
_superData = new SuperData3D ( *_cGeometry, *_loadBalancer, 2, this->_size);
this->clout << "* Reading BlockData..." << std::endl;
// Fill data objects
readSuperData(dName);
this->clout << "VTI Reader finished." << std::endl;
}
template
void SuperVTIreader3D::readCuboidGeometry()
{
//_cGeometry->clearCuboids();
for ( auto& piece : this->_xmlReader["ImageData"] ) {
if (piece->getName() == "Piece") {
std::vector extents = this->readExtent(piece, "Extent");
std::vector extent = this->getNbNodes(extents);
// int extent[i] is node number => multiply with _delta to get coordinate
Cuboid3D cuboid(extents[0] * this->_delta,
extents[2] * this->_delta,
extents[4] * this->_delta,
this->_delta,
extent[0],
extent[1],
extent[2]);
_cGeometry->add(cuboid);
}
}
}
template
void SuperVTIreader3D::readSuperData(const std::string dName)
{
int counter = 0;
// Iterate over all tags
for (auto & piece : this->_xmlReader["ImageData"]) {
if (piece->getName() == "Piece") {
this->readBlockData(_superData->get(counter), *piece, dName);
counter++;
}
}
}
template
SuperData3D& SuperVTIreader3D::getSuperData()
{
return *_superData;
}
template
CuboidGeometry3D& SuperVTIreader3D::getCuboidGeometry()
{
return *_cGeometry;
}
template
LoadBalancer& SuperVTIreader3D::getLoadBalancer()
{
return *_loadBalancer;
}
// ************************************ old 2D ********************************************** //
/*
template
void VTIreader2D::printInfo()
{
clout << "Origin: " << _x0 << " " << _y0 << std::endl;
clout << "Extend: " << _x << " " << _y << std::endl;
clout << "Spacing: " << _delta << std::endl;
}
template
VTIreader2D::VTIreader2D(const std::string& fName ) : XMLreader(fName)
{
// get _x, _y, _z
int x, y, z;
std::stringstream stream_val_0((*this)["ImageData"].getAttribute("WholeExtent"));
stream_val_0 >> x >> _x >> y >> _y >> z >> _z;
_x = _x-x+1;
_y = _y-y+1;
_z = _z-z+1;
// get _delta
std::stringstream stream_val_1((*this)["ImageData"].getAttribute("Spacing"));
stream_val_1 >> _delta;
std::stringstream stream_val_2((*this)["ImageData"].getAttribute("Origin"));
stream_val_2 >> _x0 >> _y0 >> _z0;
}
template
VTIreader2D::~VTIreader2D() {}
template
void VTIreader2D::getCuboid(Cuboid2D& cuboid)
{
cuboid.init(_x0, _y0, _delta, _x, _y);
}
template
void VTIreader2D::getCuboids(std::vector* >& cuboids)
{
std::vector::const_iterator it;
int i = 0;
for (it = (*this)["ImageData"].begin(); it != (*this)["ImageData"].end(); it++) {
if ((*it)->getName() == "Piece") {
++i;
std::stringstream extstr((*it)->getAttribute("Extent"));
int extents[6];
for (int i = 0; i < 6; ++i) {
extstr >> extents[i];
}
Cuboid2D* cuboid = new Cuboid2D(extents[0], extents[2], _delta,
extents[1]-extents[0]+1,
extents[3]-extents[2]+1);
cuboids.push_back(cuboid);
}
}
}
*/
/*
template
void VTIreader2D::getScalarMultiPieceData(std::vector* >& bases, const std::string dName)
{
std::vector::const_iterator it;
for (it = (*this)["ImageData"].begin(); it != (*this)["ImageData"].end(); it++) {
if ((*it)->getName() == "Piece") {
std::stringstream extstr((*it)->getAttribute("Extent"));
int extents[6];
for (int i = 0; i < 6; i++) {
extstr >> extents[i];
}
std::vector::const_iterator it2;
for (it2 = (*it)->operator[]("PointData").begin(); it2 != (*it)->operator[]("PointData").end(); it2++) {
if ((*it2)->getAttribute("Name") == dName && (*it2)->getName() == "DataArray") {
ScalarField2D* tmp = new ScalarField2D(extents[1]-extents[0]+1, extents[3]-extents[2]+1);
tmp->construct();
std::string data_str;
if ((*it2)->read(data_str)) {
std::stringstream stream_val(data_str);
for (int iz = 0; iz < extents[5]-extents[4]+1; iz++) {
for (int iy = 0; iy < extents[3]-extents[2]+1; iy++) {
for (int ix = 0; ix < extents[1]-extents[0]+1; ix++) {
T tmp2;
stream_val >> tmp2;
tmp->get(ix, iy) = tmp2;
}
}
}
}
bases.push_back(tmp);
}
}
}
}
}
template
void VTIreader2D::getVectorMultiPieceData(std::vector* >& bases, const std::string dName)
{
std::vector::const_iterator it;
for (it = (*this)["ImageData"].begin(); it != (*this)["ImageData"].end(); it++) {
if ((*it)->getName() == "Piece") {
std::stringstream extstr((*it)->getAttribute("Extent"));
int extents[6];
for (int i=0; i<6; i++) {
extstr >> extents[i];
}
std::vector::const_iterator it2;
for (it2 = (*it)->operator[]("PointData").begin(); it2 != (*it)->operator[]("PointData").end(); it2++) {
if ((*it2)->getAttribute("Name") == dName && (*it2)->getName() == "DataArray") {
TensorField2D* tmp = new TensorField2D(extents[1]-extents[0]+1, extents[3]-extents[2]+1);
tmp->construct();
std::string data_str;
if ((*it2)->read(data_str)) {
std::stringstream stream_val(data_str);
for (int iz = 0; iz < extents[5]-extents[4]+1; iz++) {
for (int iy = 0; iy < extents[3]-extents[2]+1; iy++) {
for (int ix = 0; ix < extents[1]-extents[0]+1; ix++) {
T tmpval;
for (int i=0; i < 2; i++) {
stream_val >> tmpval;
tmp->get(ix, iy)[i] = tmpval;
}
stream_val >> tmpval;
}
}
}
}
bases.push_back(tmp);
}
}
}
}
}
template
bool VTIreader2D::getScalarData(ScalarField2D* base, const std::string dName)
{
std::vector::const_iterator it;
for (it = (*this)["ImageData"]["Piece"]["PointData"].begin(); it != (*this)["ImageData"]["Piece"]["PointData"].end(); it++) {
if ((*it)->getAttribute("Name") == dName && (*it)->getName() == "DataArray") {
ScalarField2D* tmp = new ScalarField2D(_x, _y);
tmp->construct();
std::string data_str;
if ((*it)->read(data_str)) {
std::stringstream stream_val(data_str);
for (int iz = 0; iz < _z; iz++) {
for (int iy = 0; iy < _y; iy++) {
for (int ix = 0; ix < _x; ix++) {
T tmp2;
stream_val >> tmp2;
tmp->get(ix, iy) = tmp2;
}
}
}
}
base->swap(*tmp);
delete tmp;
return true;
}
}
return false;
}
template
bool VTIreader2D::getVectorData(TensorField2D* base, const std::string dName)
{
std::vector::const_iterator it;
for (it = (*this)["ImageData"]["Piece"]["PointData"].begin(); it != (*this)["ImageData"]["Piece"]["PointData"].end(); it++) {
if ((*it)->getAttribute("Name") == dName && (*it)->getName() == "DataArray") {
TensorField2D* tmp = new TensorField2D(_x, _y);
tmp->construct();
std::string data_str;
if ((*it)->read(data_str)) {
std::stringstream stream_val(data_str);
for (int iz = 0; iz < _z; iz++) {
for (int iy = 0; iy < _y; iy++) {
for (int ix = 0; ix < _x; ix++) {
T tmpval;
for (int i = 0; i < 2; i++) {
stream_val >> tmpval;
tmp->get(ix, iy)[i] = tmpval;
}
stream_val >> tmpval;
}
}
}
}
base->swap(*tmp);
delete tmp;
return true;
}
}
return false;
}
*/
}
#endif