Commit 250dd23e authored by Dave Moxey's avatar Dave Moxey
Browse files

Move utility classes into header

parent 1b24603a
......@@ -44,7 +44,6 @@
#include <loki/Singleton.h>
#include "zlib.h"
#include <fstream>
#include <set>
......@@ -52,9 +51,6 @@
#include <mpi.h>
#endif
// Buffer size for zlib compression/decompression
#define CHUNK 16384
#ifndef NEKTAR_VERSION
#define NEKTAR_VERSION "Unknown"
#endif
......@@ -74,21 +70,32 @@ FieldIOFactory &GetFieldIOFactory()
return Type::Instance();
}
/**
* @brief Determine file type of given input file.
*
* This method attempts to identify the file type of a given input file @p
* filename. It returns a string corresponding to GetFieldIOFactory() or throws
* an assertion if it cannot be identified.
*
* @param filename Input filename
* @param comm Communicator for parallel runs
*
* @return FieldIO format of @p filename.
*/
const std::string FieldIO::GetFileType(const std::string &filename,
CommSharedPtr comm)
{
// We'll use 0 => XML
// and 1 => HDF5
// We'll use 0 => XML and 1 => HDF5.
int code = 0;
int size = comm->GetSize();
int rank = comm->GetRank();
if (size == 1 || rank == 0)
{
std::string datafilename;
if (fs::is_directory(
filename)) // check to see that infile is a directory
// If input is a directory, check for root processor file.
if (fs::is_directory(filename))
{
fs::path p0file("P0000000.fld");
fs::path fullpath = filename / p0file;
......@@ -98,12 +105,10 @@ const std::string FieldIO::GetFileType(const std::string &filename,
{
datafilename = filename;
}
// Read first 8 bytes
// If they are (in hex) 89 48 44 46 0d 0a 1a 0a
// then it's an HDF5 file.
// XML is potentially a nightmare with all the different encodings
// so we'll just assume it's OK if it's not HDF
// Read first 8 bytes. If they correspond with magic bytes below it's an
// HDF5 file. XML is potentially a nightmare with all the different
// encodings so we'll just assume it's OK if it's not HDF.
const char magic[8] = {0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
std::ifstream datafile(datafilename.c_str(), ios_base::binary);
......@@ -122,19 +127,39 @@ const std::string FieldIO::GetFileType(const std::string &filename,
}
if (size > 1)
{
comm->Bcast(code, 0);
}
std::string iofmt;
if (code == 0)
{
iofmt = "Xml";
}
else if (code == 1)
{
iofmt = "Hdf5";
}
else
{
// Error
ASSERTL0(false, "Unknown file format");
}
return iofmt;
}
/**
* @brief Construct a FieldIO object for a given input filename.
*
* This is a convenience function that takes an input filename and constructs
* the appropriate FieldIO subclass, using FieldIO::GetFileType.
*
* @param session Session reader
* @param filename Input filename
*
* @return FieldIO class reader for @p filename.
*/
FieldIOSharedPtr MakeFieldIOForFile(
const LibUtilities::SessionReaderSharedPtr session,
const std::string &filename)
......@@ -146,10 +171,11 @@ FieldIOSharedPtr MakeFieldIOForFile(
session->GetComm(),
session->DefinesCmdLineArgument("shared-filesystem"));
}
/**
* This function allows for data to be written to an FLD file when a
* session and/or communicator is not instantiated. Typically used in
* utilities which do not take XML input and operate in serial only.
* @brief This function allows for data to be written to an FLD file when a
* session and/or communicator is not instantiated. Typically used in utilities
* which do not take XML input and operate in serial only.
*/
void Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
......@@ -180,9 +206,9 @@ void Write(const std::string &outFile,
}
/**
* This function allows for data to be imported from an FLD file when
* a session and/or communicator is not instantiated. Typically used in
* utilities which only operate in serial.
* @brief This function allows for data to be imported from an FLD file when a
* session and/or communicator is not instantiated. Typically used in utilities
* which only operate in serial.
*/
LIB_UTILITIES_EXPORT void Import(
const std::string &infilename,
......@@ -215,44 +241,13 @@ LIB_UTILITIES_EXPORT void Import(
}
/**
*
* @brief Constructor for FieldIO base class.
*/
FieldIO::FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
: m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
{
}
/**
* \brief add information about provenance and fieldmetadata
*/
void FieldIO::AddInfoTag(TiXmlElement *root,
const FieldMetaDataMap &fieldmetadatamap)
{
TagWriterSharedPtr w = boost::make_shared<XmlTagWriter>(root);
AddInfoTag(w, fieldmetadatamap);
}
TagWriter::~TagWriter()
{
}
XmlTagWriter::XmlTagWriter(TiXmlElement *elem) : m_El(elem)
{
}
TagWriterSharedPtr XmlTagWriter::AddChild(const std::string &name)
{
TiXmlElement *child = new TiXmlElement(name.c_str());
m_El->LinkEndChild(child);
return TagWriterSharedPtr(new XmlTagWriter(child));
}
void XmlTagWriter::SetAttr(const std::string &key, const std::string &val)
{
TiXmlElement *child = new TiXmlElement(key.c_str());
child->LinkEndChild(new TiXmlText(val.c_str()));
m_El->LinkEndChild(child);
}
void FieldIO::AddInfoTag(TagWriterSharedPtr root,
const FieldMetaDataMap &fieldmetadatamap)
{
......
......@@ -51,32 +51,23 @@ namespace Nektar
{
namespace LibUtilities
{
/// Base class for writing hierarchical data (XML or HDF5)
/**
* @brief Base class for writing hierarchical data (XML or HDF5).
*/
class TagWriter
{
public:
/// Create a child node
/// Create a child node.
virtual boost::shared_ptr<TagWriter> AddChild(const std::string &name) = 0;
/// Set an attribute on the node
/// Set an attribute on the node.
virtual void SetAttr(const std::string &key, const std::string &val) = 0;
protected:
virtual ~TagWriter();
virtual ~TagWriter() {}
};
typedef boost::shared_ptr<TagWriter> TagWriterSharedPtr;
/// Simple class for writing to XML
class XmlTagWriter : public TagWriter
{
public:
XmlTagWriter(TiXmlElement *elem);
TagWriterSharedPtr AddChild(const std::string &name);
void SetAttr(const std::string &key, const std::string &val);
private:
TiXmlElement *m_El;
};
static std::vector<NekDouble> NullNekDoubleVector;
static std::vector<LibUtilities::PointsType> NullPointsTypeVector;
static std::vector<unsigned int> NullUnsignedIntVector;
......@@ -86,10 +77,43 @@ static FieldMetaDataMap NullFieldMetaDataMap;
static std::vector<std::vector<NekDouble> > NullVectorNekDoubleVector =
boost::assign::list_of(NullNekDoubleVector);
/**
* @class A simple class encapsulating a data source. This allows us to pass
* around native file formats in virtual functions without resorting to using
* the filename.
*/
class DataSource
{
};
typedef boost::shared_ptr<DataSource> DataSourceSharedPtr;
/**
* @brief Metadata that describes the storage properties of field output.
*
* The purpose of this struct is to describe the format of binary field data.
* This can then be used in the library to determine appropriate actions. For
* example, when restarting a simulation, the information this struct
* encapsulates can be used to determine whether interpolation is required to a
* different polynomial order depending on the order of the simulation versus
* the order of the restart file.
*
* We note that some of the parameters here include:
*
* - Element shape type and the basis used
* - Element IDs, which determines the order of data written in a field
* - The field names (e.g. u for x-velocity) so that multi-field storage can be
* agglomerated into one data block. Each field is written in the order
* specified here.
* - Number of modes, including support for variable polynomial order
* - Homogeneous information (dimension of homogeneity, IDs of planes and/or
* strips if they are used)
*/
struct FieldDefinitions
{
/// Default constructor
FieldDefinitions() {}
/// Simple constructor to allocate all internal properties.
FieldDefinitions(
ShapeType shapeType,
const std::vector<unsigned int> &elementIDs, // vector[2]
......@@ -118,45 +142,49 @@ struct FieldDefinitions
{
}
ShapeType m_shapeType;
std::vector<unsigned int> m_elementIDs;
std::vector<LibUtilities::BasisType> m_basis;
int m_numHomogeneousDir;
std::vector<NekDouble> m_homogeneousLengths;
bool m_homoStrips;
std::vector<unsigned int> m_homogeneousSIDs;
std::vector<unsigned int> m_homogeneousZIDs;
std::vector<unsigned int> m_homogeneousYIDs;
/// Shape type of this field data.
ShapeType m_shapeType;
/// Element IDs of the field data.
std::vector<unsigned int> m_elementIDs;
/// Vector of basis types for each of the coordinate directions.
std::vector<LibUtilities::BasisType> m_basis;
/// Number of homogeneous directions, in the range \f$ 0\leq d \leq 3 \f$.
int m_numHomogeneousDir;
/// Spatial lengths of each homogeneous direction.
std::vector<NekDouble> m_homogeneousLengths;
/// Boolean determining whether homogeneous strips are used.
bool m_homoStrips;
/// IDs corresponding to homogeneous strip IDs.
std::vector<unsigned int> m_homogeneousSIDs;
/// IDs corresponding to z-direction homogeneous IDs.
std::vector<unsigned int> m_homogeneousZIDs;
/// IDs corresponding to y-direction homogeneous IDs.
std::vector<unsigned int> m_homogeneousYIDs;
/// Define the type of points per direction.
std::vector<LibUtilities::PointsType> m_points;
bool m_pointsDef;
/// Boolean determining whether points have been defined in output.
bool m_pointsDef;
/// Define order of the element group.
/// * UniOrder: same order for each element
/// * MixOrder: definition of a different order for each element.
bool m_uniOrder;
bool m_uniOrder;
/// Define number of modes per direction.
std::vector<unsigned int> m_numModes;
std::vector<unsigned int> m_numPoints;
bool m_numPointsDef;
std::vector<std::string> m_fields;
std::vector<unsigned int> m_numModes;
/// Define number of points per direction.
std::vector<unsigned int> m_numPoints;
/// Boolean determining whether number of points has been defined.
bool m_numPointsDef;
/// Vector of field names that this data encapsulates.
std::vector<std::string> m_fields;
};
typedef boost::shared_ptr<FieldDefinitions> FieldDefinitionsSharedPtr;
class DataSource
{
};
typedef boost::shared_ptr<DataSource> DataSourceSharedPtr;
/// Write a field file in serial only
LIB_UTILITIES_EXPORT void Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
/// Imports an FLD file
LIB_UTILITIES_EXPORT void Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
......@@ -179,76 +207,56 @@ LIB_UTILITIES_EXPORT FieldIOFactory &GetFieldIOFactory();
class FieldIO : public boost::enable_shared_from_this<FieldIO>
{
public:
/// Constructor
LIB_UTILITIES_EXPORT
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem);
LIB_UTILITIES_EXPORT FieldIO(
LibUtilities::CommSharedPtr pComm, bool sharedFilesystem);
/// Write data in FLD format
LIB_UTILITIES_EXPORT
inline void Write(
LIB_UTILITIES_EXPORT inline void Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
/// Imports an FLD file.
LIB_UTILITIES_EXPORT
inline void Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata =
NullVectorNekDoubleVector,
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> ElementiDs = NullInt1DArray);
/// Imports the definition of the meta data
LIB_UTILITIES_EXPORT
DataSourceSharedPtr ImportFieldMetaData(std::string filename,
FieldMetaDataMap &fieldmetadatamap);
/// Imports the definition of the fields.
LIB_UTILITIES_EXPORT
virtual void ImportFieldDefs(
DataSourceSharedPtr dataSource,
LIB_UTILITIES_EXPORT inline void Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
bool expChild) = 0;
std::vector<std::vector<NekDouble> > &fielddata =
NullVectorNekDoubleVector,
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> ElementiDs = NullInt1DArray);
LIB_UTILITIES_EXPORT DataSourceSharedPtr ImportFieldMetaData(
std::string filename,
FieldMetaDataMap &fieldmetadatamap);
// Figure out what type of FLD file we have.
// Collective on comm.
static const std::string GetFileType(const std::string &filename,
CommSharedPtr comm);
virtual const std::string &GetClassName() const = 0;
protected:
/// Communicator to use when writing parallel format
LibUtilities::CommSharedPtr m_comm;
bool m_sharedFilesystem;
LIB_UTILITIES_EXPORT
void AddInfoTag(TiXmlElement *root,
const FieldMetaDataMap &fieldmetadatamap);
/// Boolean dictating whether we are on a shared filesystem.
bool m_sharedFilesystem;
LIB_UTILITIES_EXPORT
void AddInfoTag(TagWriterSharedPtr root,
const FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void AddInfoTag(
TagWriterSharedPtr root,
const FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs);
LIB_UTILITIES_EXPORT int CheckFieldDefinition(
const FieldDefinitionsSharedPtr &fielddefs);
LIB_UTILITIES_EXPORT virtual std::string GetFileEnding() const
{
return "fld";
}
LIB_UTILITIES_EXPORT
virtual void v_Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap) = 0;
LIB_UTILITIES_EXPORT virtual void v_Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap) = 0;
/// Imports an FLD file.
LIB_UTILITIES_EXPORT
virtual void v_Import(
LIB_UTILITIES_EXPORT virtual void v_Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> >
......@@ -256,8 +264,7 @@ protected:
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> ElementiDs = NullInt1DArray) = 0;
LIB_UTILITIES_EXPORT
virtual DataSourceSharedPtr v_ImportFieldMetaData(
LIB_UTILITIES_EXPORT virtual DataSourceSharedPtr v_ImportFieldMetaData(
std::string filename, FieldMetaDataMap &fieldmetadatamap) = 0;
};
......@@ -267,35 +274,36 @@ inline FieldIOSharedPtr MakeDefaultFieldIO(
const LibUtilities::SessionReaderSharedPtr session)
{
std::string iofmt("Xml");
if (session->DefinesSolverInfo("FieldIO_Format"))
if (session->DefinesSolverInfo("FieldIOFormat"))
{
iofmt = session->GetSolverInfo("FieldIO_Format");
iofmt = session->GetSolverInfo("FieldIOFormat");
}
return GetFieldIOFactory().CreateInstance(
iofmt,
session->GetComm(),
session->DefinesCmdLineArgument("shared-filesystem"));
}
// Collective on session's communicator
FieldIOSharedPtr MakeFieldIOForFile(
const LibUtilities::SessionReaderSharedPtr session,
const std::string &filename);
inline void FieldIO::Write(const std::string &outFile,
inline void FieldIO::Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap)
const FieldMetaDataMap &fieldinfomap)
{
v_Write(outFile, fielddefs, fielddata, fieldinfomap);
}
inline void FieldIO::Import(const std::string &infilename,
inline void FieldIO::Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfomap,
const Array<OneD, int> ElementiDs)
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfo,
const Array<OneD, int> ElementiDs)
{
v_Import(infilename, fielddefs, fielddata, fieldinfomap, ElementiDs);
v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementiDs);
}
inline DataSourceSharedPtr FieldIO::ImportFieldMetaData(
......@@ -303,6 +311,7 @@ inline DataSourceSharedPtr FieldIO::ImportFieldMetaData(
{
return v_ImportFieldMetaData(filename, fieldmetadatamap);
}
}
}
#endif
......@@ -44,50 +44,14 @@ namespace LibUtilities
{
namespace H5
{
template <> inline DataTypeSharedPtr DataTypeTraits<BasisType>::GetType()
{
return PredefinedDataType::Native<int>();
}
}
H5TagWriter::H5TagWriter(H5::GroupSharedPtr grp) : m_Group(grp)
{
}
TagWriterSharedPtr H5TagWriter::AddChild(const std::string &name)
{
H5::GroupSharedPtr child = m_Group->CreateGroup(name);
return TagWriterSharedPtr(new H5TagWriter(child));
};
void H5TagWriter::SetAttr(const std::string &key, const std::string &val)
{
m_Group->SetAttribute(key, val);
}
class H5DataSource : public DataSource
{
H5::FileSharedPtr doc;
public:
H5DataSource(const std::string &fn)
: doc(H5::File::Open(fn, H5F_ACC_RDONLY))
{
}
H5::FileSharedPtr Get()
{
return doc;
}
const H5::FileSharedPtr Get() const
{
return doc;
}
static DataSourceSharedPtr create(const std::string &fn)
{
return DataSourceSharedPtr(new H5DataSource(fn));
}
};
typedef boost::shared_ptr<H5DataSource> H5DataSourceSharedPtr;
std::string FieldIOHdf5::className =
GetFieldIOFactory().RegisterCreatorFunction(
......@@ -118,7 +82,8 @@ void FieldIOHdf5::v_Write(const std::string &outFile,
std::stringstream prfx;
prfx << m_comm->GetRank() << ": FieldIOHdf5::v_Write(): ";
double tm0 = 0.0, tm1 = 0.0;
if (0 == m_comm->GetRank())
if (m_comm->GetRank() == 0)
{
cout << prfx.str() << "entering..." << endl;
tm0 = m_comm->Wtime();
......@@ -365,8 +330,6 @@ void FieldIOHdf5::v_Write(const std::string &outFile,
H5::DataSetSharedPtr data_dset =
root->CreateDataSet("DATA", data_type, data_space);
ASSERTL1(data_dset, prfx.str() + "cannot create DATA dataset.");
// Field group is closed automatically at end of scope
}
// Datasets, root group and HDF5 file are all closed automatically since
......@@ -742,9 +705,9 @@ void FieldIOHdf5::v_Import(const std::string &infilename,
}
void FieldIOHdf5::ImportFieldDef(
H5::PListSharedPtr readPL,
H5::GroupSharedPtr root,
std::string group,
H5::PListSharedPtr readPL,
H5::GroupSharedPtr root,
std::string group,
FieldDefinitionsSharedPtr def)
{
std::stringstream prfx;
......@@ -914,14 +877,14 @@ void FieldIOHdf5::ImportFieldDef(
}
void FieldIOHdf5::ImportFieldData(
H5::PListSharedPtr readPL,
H5::DataSetSharedPtr data_dset,
H5::DataSpaceSharedPtr data_fspace,
size_t data_i,
std::vector<std::size_t> &decomps,
size_t decomp,
const FieldDefinitionsSharedPtr fielddef,
std::vector<NekDouble> &fielddata)
H5::PListSharedPtr readPL,
H5::DataSetSharedPtr data_dset,
H5::DataSpaceSharedPtr data_fspace,
size_t data_i,
std::vector<std::size_t> &decomps,
size_t decomp,
const FieldDefinitionsSharedPtr fielddef,
std::vector<NekDouble> &fielddata)
{