Commit be7a6349 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Finish IO of XdmfGridRegular. Begin implementation of XdmfGridRectilinear.

parent 62be8bc4
...@@ -135,6 +135,7 @@ if(NOT XDMF_BUILD_CORE_ONLY) ...@@ -135,6 +135,7 @@ if(NOT XDMF_BUILD_CORE_ONLY)
XdmfGrid XdmfGrid
XdmfGridCollection XdmfGridCollection
XdmfGridCollectionType XdmfGridCollectionType
XdmfGridRectilinear
XdmfGridRegular XdmfGridRegular
XdmfItemFactory XdmfItemFactory
XdmfMap XdmfMap
......
...@@ -99,12 +99,6 @@ boost::shared_ptr<const XdmfGeometryType> XdmfGeometryType::New(const std::map<s ...@@ -99,12 +99,6 @@ boost::shared_ptr<const XdmfGeometryType> XdmfGeometryType::New(const std::map<s
{ {
return VXVY(); return VXVY();
} }
else if(typeVal.compare("ORIGIN_DXDY") == 0 || typeVal.compare("ORIGIN_DXDYDZ") == 0)
{
// Special case --- Regular Grid
boost::shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("REGULAR", 0));
return p;
}
else else
{ {
assert(false); assert(false);
......
...@@ -71,13 +71,13 @@ public: ...@@ -71,13 +71,13 @@ public:
*/ */
bool operator!=(const XdmfGeometryType & geometryType) const; bool operator!=(const XdmfGeometryType & geometryType) const;
/** /**
* Compare two XdmfGeometryType for equality (for wrapping) * Compare two XdmfGeometryType for equality (for wrapping)
* *
* @param geometryType a boost shared pointer to an XdmfGeometryType to compare equality to. * @param geometryType a boost shared pointer to an XdmfGeometryType to compare equality to.
* @return true if the XdmfGeometryType are equal. * @return true if the XdmfGeometryType are equal.
*/ */
bool IsEqual(boost::shared_ptr<XdmfGeometryType> geometryType); bool IsEqual(boost::shared_ptr<XdmfGeometryType> geometryType);
protected: protected:
......
/*
* XdmfGridRectilinear.cpp
*
* Created on: Jan 25, 2010
* Author: kleiter
*/
#include <cmath>
#include "XdmfArray.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfGeometryType.hpp"
#include "XdmfGridRectilinear.hpp"
#include "XdmfTopology.hpp"
#include "XdmfTopologyType.hpp"
/**
* PIMPL
*/
class XdmfGridRectilinear::XdmfGridRectilinearImpl {
public:
class XdmfGeometryRectilinear : public XdmfGeometry
{
public:
static boost::shared_ptr<XdmfGeometryRectilinear> New(XdmfGridRectilinear * const rectilinearGrid)
{
boost::shared_ptr<XdmfGeometryRectilinear> p(new XdmfGeometryRectilinear(rectilinearGrid));
return p;
}
unsigned int getNumberPoints() const
{
const boost::shared_ptr<const XdmfArray> dimensions = mRectilinearGrid->getDimensions();
if(dimensions->getSize() == 0)
{
return 0;
}
unsigned int toReturn = 1;
for(unsigned int i=0; i<dimensions->getSize(); ++i)
{
toReturn *= dimensions->getValue<unsigned int>(i);
}
return toReturn;
}
void traverse(const boost::shared_ptr<XdmfBaseVisitor> visitor)
{
const std::vector<boost::shared_ptr<XdmfArray> > & coordinates = mRectilinearGrid->getCoordinates();
for(std::vector<boost::shared_ptr<XdmfArray> >::const_iterator iter = coordinates.begin(); iter != coordinates.end(); ++iter)
{
(*iter)->accept(visitor);
}
}
private:
XdmfGeometryRectilinear(XdmfGridRectilinear * const rectilinearGrid) :
mRectilinearGrid(rectilinearGrid)
{
this->setType(XdmfGeometryTypeRectilinear::New(mRectilinearGrid));
}
XdmfGridRectilinear * const mRectilinearGrid;
};
class XdmfGeometryTypeRectilinear : public XdmfGeometryType
{
public:
static boost::shared_ptr<const XdmfGeometryTypeRectilinear> New(const XdmfGridRectilinear * const rectilinearGrid)
{
boost::shared_ptr<const XdmfGeometryTypeRectilinear> p(new XdmfGeometryTypeRectilinear(rectilinearGrid));
return p;
}
unsigned int getDimensions() const
{
return mRectilinearGrid->getDimensions()->getSize();
}
void getProperties(std::map<std::string, std::string> & collectedProperties) const
{
const unsigned int dimensions = this->getDimensions();
if(dimensions == 3)
{
collectedProperties["Type"] = "ORIGIN_DXDYDZ";
}
else if(dimensions == 2)
{
collectedProperties["Type"] = "ORIGIN_DXDY";
}
else
{
assert(false);
}
}
private:
XdmfGeometryTypeRectilinear(const XdmfGridRectilinear * const rectilinearGrid) :
XdmfGeometryType("", 0),
mRectilinearGrid(mRectilinearGrid)
{
}
const XdmfGridRectilinear * const mRectilinearGrid;
};
class XdmfTopologyRectilinear : public XdmfTopology
{
public:
static boost::shared_ptr<XdmfTopologyRectilinear> New(const XdmfGridRectilinear * const rectilinearGrid)
{
boost::shared_ptr<XdmfTopologyRectilinear> p(new XdmfTopologyRectilinear(rectilinearGrid));
return p;
}
unsigned int getNumberElements() const
{
const boost::shared_ptr<const XdmfArray> dimensions = mRectilinearGrid->getDimensions();
if(dimensions->getSize() == 0)
{
return 0;
}
unsigned int toReturn = 1;
for(unsigned int i=0; i<dimensions->getSize(); ++i)
{
toReturn *= (dimensions->getValue<unsigned int>(i) - 1);
}
return toReturn;
}
private:
XdmfTopologyRectilinear(const XdmfGridRectilinear * const rectilinearGrid) :
mRectilinearGrid(rectilinearGrid)
{
this->setType(XdmfTopologyTypeRectilinear::New(rectilinearGrid));
}
const XdmfGridRectilinear * const mRectilinearGrid;
};
class XdmfTopologyTypeRectilinear : public XdmfTopologyType
{
public:
static boost::shared_ptr<const XdmfTopologyTypeRectilinear> New(const XdmfGridRectilinear * const rectilinearGrid)
{
boost::shared_ptr<const XdmfTopologyTypeRectilinear> p(new XdmfTopologyTypeRectilinear(rectilinearGrid));
return p;
}
unsigned int getNodesPerElement() const
{
// 2^Dimensions
// e.g. 1D = 2 nodes per element and 2D = 4 nodes per element.
return (unsigned int)std::pow(2, (double)mRectilinearGrid->getDimensions()->getSize());
}
void getProperties(std::map<std::string, std::string> & collectedProperties) const
{
boost::shared_ptr<const XdmfArray> dimensions = mRectilinearGrid->getDimensions();
if(dimensions->getSize() == 3)
{
collectedProperties["Type"] = "3DRectMesh";
}
else if(dimensions->getSize() == 2)
{
collectedProperties["Type"] = "2DRectMesh";
}
else
{
assert(false);
}
collectedProperties["Dimensions"] = dimensions->getValuesString();
}
private:
XdmfTopologyTypeRectilinear(const XdmfGridRectilinear * const rectilinearGrid) :
XdmfTopologyType(0, "foo", XdmfTopologyType::Structured),
mRectilinearGrid(rectilinearGrid)
{
}
const XdmfGridRectilinear * const mRectilinearGrid;
};
XdmfGridRectilinearImpl(const std::vector<boost::shared_ptr<XdmfArray> > & coordinates) :
mCoordinates(coordinates.begin(), coordinates.end())
{
}
std::vector<boost::shared_ptr<XdmfArray> > mCoordinates;
};
boost::shared_ptr<XdmfGridRectilinear> XdmfGridRectilinear::New(const boost::shared_ptr<XdmfArray> xCoordinates,
const boost::shared_ptr<XdmfArray> yCoordinates)
{
std::vector<boost::shared_ptr<XdmfArray> > axesCoordinates;
axesCoordinates.resize(2);
axesCoordinates[0] = xCoordinates;
axesCoordinates[1] = yCoordinates;
boost::shared_ptr<XdmfGridRectilinear> p(new XdmfGridRectilinear(axesCoordinates));
return p;
}
boost::shared_ptr<XdmfGridRectilinear> XdmfGridRectilinear::New(const boost::shared_ptr<XdmfArray> xCoordinates,
const boost::shared_ptr<XdmfArray> yCoordinates, const boost::shared_ptr<XdmfArray> zCoordinates)
{
std::vector<boost::shared_ptr<XdmfArray> > axesCoordinates;
axesCoordinates.resize(3);
axesCoordinates[0] = xCoordinates;
axesCoordinates[1] = yCoordinates;
axesCoordinates[2] = zCoordinates;
boost::shared_ptr<XdmfGridRectilinear> p(new XdmfGridRectilinear(axesCoordinates));
return p;
}
boost::shared_ptr<XdmfGridRectilinear> XdmfGridRectilinear::New(const std::vector<boost::shared_ptr<XdmfArray> > & axesCoordinates)
{
boost::shared_ptr<XdmfGridRectilinear> p(new XdmfGridRectilinear(axesCoordinates));
return p;
}
XdmfGridRectilinear::XdmfGridRectilinear(const std::vector<boost::shared_ptr<XdmfArray> > & axesCoordinates) :
mImpl(new XdmfGridRectilinearImpl(axesCoordinates))
{
this->setGeometry(XdmfGridRectilinearImpl::XdmfGeometryRectilinear::New(this));
this->setTopology(XdmfGridRectilinearImpl::XdmfTopologyRectilinear::New(this));
}
XdmfGridRectilinear::~XdmfGridRectilinear()
{
delete mImpl;
}
const std::string XdmfGridRectilinear::ItemTag = "Grid";
boost::shared_ptr<XdmfArray> XdmfGridRectilinear::getCoordinates(const unsigned int axisIndex)
{
return boost::const_pointer_cast<XdmfArray>(static_cast<const XdmfGridRectilinear &>(*this).getCoordinates(axisIndex));
}
boost::shared_ptr<const XdmfArray> XdmfGridRectilinear::getCoordinates(const unsigned int axisIndex) const
{
if(axisIndex < mImpl->mCoordinates.size())
{
return mImpl->mCoordinates[axisIndex];
}
return boost::shared_ptr<XdmfArray>();
}
std::vector<boost::shared_ptr<XdmfArray> > XdmfGridRectilinear::getCoordinates()
{
return mImpl->mCoordinates;
}
const std::vector<boost::shared_ptr<XdmfArray> > XdmfGridRectilinear::getCoordinates() const
{
return mImpl->mCoordinates;
}
boost::shared_ptr<XdmfArray> XdmfGridRectilinear::getDimensions()
{
return boost::const_pointer_cast<XdmfArray>(static_cast<const XdmfGridRectilinear &>(*this).getDimensions());
}
boost::shared_ptr<const XdmfArray> XdmfGridRectilinear::getDimensions() const
{
boost::shared_ptr<XdmfArray> dimensions = XdmfArray::New();
dimensions->reserve(mImpl->mCoordinates.size());
for(std::vector<boost::shared_ptr<XdmfArray> >::const_iterator iter = mImpl->mCoordinates.begin(); iter != mImpl->mCoordinates.end(); ++iter)
{
dimensions->pushBack((*iter)->getSize());
}
return dimensions;
}
void XdmfGridRectilinear::populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems, const XdmfCoreReader * const reader)
{
XdmfGrid::populateItem(itemProperties, childItems, reader);
for(std::vector<boost::shared_ptr<XdmfItem> >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter)
{
if(boost::shared_ptr<XdmfGridRectilinear> rectilinearGrid = boost::shared_dynamic_cast<XdmfGridRectilinear>(*iter))
{
this->setCoordinates(rectilinearGrid->getCoordinates());
break;
}
}
}
void XdmfGridRectilinear::setCoordinates(const unsigned int axisIndex, const boost::shared_ptr<XdmfArray> axisCoordinates)
{
if(mImpl->mCoordinates.size() <= axisIndex)
{
mImpl->mCoordinates.reserve(axisIndex + 1);
unsigned int numArraysToInsert = axisIndex - mImpl->mCoordinates.size() + 1;
for(unsigned int i=0; i<numArraysToInsert; ++i)
{
mImpl->mCoordinates.push_back(XdmfArray::New());
}
}
mImpl->mCoordinates[axisIndex] = axisCoordinates;
}
void XdmfGridRectilinear::setCoordinates(const std::vector<boost::shared_ptr<XdmfArray> > axesCoordinates)
{
mImpl->mCoordinates = axesCoordinates;
}
#ifndef XDMFGRIDRECTILINEAR_HPP_
#define XDMFGRIDRECTILINEAR_HPP_
// Includes
#include "XdmfGrid.hpp"
/**
* @brief A mesh consisting of cells and points arranged on a regular lattice in space.
*
* XdmfGridRectilinear represents a mesh of cells and point arranged on a regular lattice in space.
* Points are arranged along coordinate axes, but the spacing between points may vary.
*
* In order to define a rectilinear grid, the coordinates along each axis direction
* must be specified.
*
*/
class XdmfGridRectilinear : public XdmfGrid {
public:
/**
* Create a new rectilinear grid (Two dimensional).
*
* @param xCoordinates the coordinates of points along the x axis
* @param yCoordinates the coordinates of points along the y axis.
*
* @return constructed rectilinear grid.
*/
static boost::shared_ptr<XdmfGridRectilinear> New(const boost::shared_ptr<XdmfArray> xCoordinates, const boost::shared_ptr<XdmfArray> yCoordinates);
/**
* Create a new rectilinear grid (Three dimensional).
*
* @param xCoordinates the coordinates of points along the x axis
* @param yCoordinates the coordinates of points along the y axis.
* @param zCoordinates the coordinates of points along the z axis.
*
* @return constructed rectilinear grid.
*/
static boost::shared_ptr<XdmfGridRectilinear> New(const boost::shared_ptr<XdmfArray> xCoordinates, const boost::shared_ptr<XdmfArray> yCoordinates,
const boost::shared_ptr<XdmfArray> zCoordinates);
/**
* Create a new rectilinear grid (N dimensional).
*
* @param axesCoordinates the coordinates of points along each axis.
*
* @return constructed rectilinear grid.
*/
static boost::shared_ptr<XdmfGridRectilinear> New(const std::vector<boost::shared_ptr<XdmfArray> > & axesCoordinates);
virtual ~XdmfGridRectilinear();
LOKI_DEFINE_VISITABLE(XdmfGridRectilinear, XdmfGrid)
static const std::string ItemTag;
/**
* Get the coordinates of the grid along a single axis.
*
* @param axisIndex the index of the axis to retrieve, (i.e. 0 for x-axis). If no array exists at the index, return NULL.
*
* @return array of coordinates along
*/
boost::shared_ptr<XdmfArray> getCoordinates(const unsigned int axisIndex);
/**
* Get the coordinates of the grid along a single axis (const version).
*
* @param axisIndex the index of the axis to retrieve (i.e. 0 for x-axis). If no array exists at the index, return NULL.
*
* @return array of coordinates along
*/
boost::shared_ptr<const XdmfArray> getCoordinates(const unsigned int axisIndex) const;
/**
* Get the coordinates of the grid along all axes.
*
* @return vector containing an array of coordinates along each direction.
*/
std::vector<boost::shared_ptr<XdmfArray> > getCoordinates();
/**
* Get the coordinates of the grid along all axes (const version).
*
* @return vector containing an array of coordinates along each direction.
*/
const std::vector<boost::shared_ptr<XdmfArray> > getCoordinates() const;
/**
* Get the dimensions of the grid, the number of points in each direction.
*
* @return XdmfArray containing dimensions of this grid.
*/
boost::shared_ptr<XdmfArray> getDimensions();
/**
* Get the dimensions of the grid, the number of points in each direction (const version).
*
* @return XdmfArray containing the dimensions of this grid.
*/
boost::shared_ptr<const XdmfArray> getDimensions() const;
/**
* Set the coordinates of the grid along a single axis.
*
* @param axisIndex the index of the axis to set (i.e. 0 for x-axis).
* @param axisCoordinates the coordinates of points along a single axis to set.
*/
void setCoordinates(const unsigned int axisIndex, const boost::shared_ptr<XdmfArray> axisCoordinates);
/**
* Set the coordinates of the grid along all axes.
*
* @param axesCoordinates the coordinates of points along each axis.
*/
void setCoordinates(const std::vector<boost::shared_ptr<XdmfArray> > axesCoordinates);
protected:
XdmfGridRectilinear(const std::vector<boost::shared_ptr<XdmfArray> > & axesCoordinates);
void populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems, const XdmfCoreReader * const reader);
private:
/**
* PIMPL
*/
class XdmfGridRectilinearImpl;
XdmfGridRectilinear(const XdmfGridRectilinear & grid); // Not implemented.
void operator=(const XdmfGridRectilinear & grid); // Not implemented.
XdmfGridRectilinearImpl * mImpl;
};
#endif /* XDMFGRIDRECTILINEAR_HPP_ */
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
* Author: kleiter * Author: kleiter
*/ */
#include <boost/tokenizer.hpp>
#include <cmath> #include <cmath>
#include "XdmfArray.hpp" #include "XdmfArray.hpp"
#include "XdmfGeometry.hpp" #include "XdmfGeometry.hpp"
...@@ -60,7 +59,7 @@ public: ...@@ -60,7 +59,7 @@ public:
XdmfGeometryRegular(XdmfGridRegular * const regularGrid) : XdmfGeometryRegular(XdmfGridRegular * const regularGrid) :
mRegularGrid(regularGrid) mRegularGrid(regularGrid)
{ {
this->setType(XdmfGeometryTypeRegular::New(regularGrid)); this->setType(XdmfGeometryTypeRegular::New(mRegularGrid));
} }
XdmfGridRegular * const mRegularGrid; XdmfGridRegular * const mRegularGrid;
...@@ -84,12 +83,12 @@ public: ...@@ -84,12 +83,12 @@ public:
void getProperties(std::map<std::string, std::string> & collectedProperties) const void getProperties(std::map<std::string, std::string> & collectedProperties) const
{ {
const boost::shared_ptr<const XdmfArray> dimensions = mRegularGrid->getDimensions(); const unsigned int dimensions = this->getDimensions();
if(dimensions->getSize() == 3) if(dimensions == 3)
{ {
collectedProperties["Type"] = "ORIGIN_DXDYDZ"; collectedProperties["Type"] = "ORIGIN_DXDYDZ";
} }
else if(dimensions->getSize() == 2) else if(dimensions == 2)
{ {
collectedProperties["Type"] = "ORIGIN_DXDY"; collectedProperties["Type"] = "ORIGIN_DXDY";
} }
...@@ -196,14 +195,11 @@ public: ...@@ -196,14 +195,11 @@ public:
}; };
XdmfGridRegularImpl(const unsigned int dimension) : XdmfGridRegularImpl(const boost::shared_ptr<XdmfArray> brickSize, const boost::shared_ptr<XdmfArray> numPoints, const boost::shared_ptr<XdmfArray> origin) :
mBrickSize(XdmfArray::New()), mBrickSize(brickSize),
mDimensions(XdmfArray::New()), mDimensions(numPoints),
mOrigin(XdmfArray::New()) mOrigin(origin)
{ {
mBrickSize->initialize<double>(dimension);
mDimensions->initialize<unsigned int>(dimension);
mOrigin->initialize<double>(dimension);
} }
boost::shared_ptr<XdmfArray> mBrickSize; boost::shared_ptr<XdmfArray> mBrickSize;
...@@ -215,7 +211,19 @@ public: ...@@ -215,7 +211,19 @@ public:
boost::shared_ptr<XdmfGridRegular> XdmfGridRegular::New(const double brickSizeX, const double brickSizeY, const unsigned int numPointsX, boost::shared_ptr<XdmfGridRegular> XdmfGridRegular::New(const double brickSizeX, const double brickSizeY, const unsigned int numPointsX,
const unsigned int numPointsY, const double originX, const double originY) const unsigned int numPointsY, const double originX, const double originY)
{ {
boost::shared_ptr<XdmfGridRegular> p(new XdmfGridRegular(brickSizeX, brickSizeY, numPointsX, numPointsY, originX, originY)); boost::shared_ptr<XdmfArray> brickSize = XdmfArray::New();
brickSize->resize<double>(2);
brickSize->insert(0, brickSizeX);
brickSize->insert(1, brickSizeY);
boost::shared_ptr<XdmfArray> numPoints = XdmfArray::New();
numPoints->resize<unsigned int>(2);
numPoints->insert(0, numPointsX);
numPoints->insert(1, numPointsY);
boost::shared_ptr<XdmfArray> origin = XdmfArray::New();
origin->resize<double>(2);
origin->insert(0, originX);
origin->insert(1, originY);
boost::shared_ptr<XdmfGridRegular> p(new XdmfGridRegular(brickSize, numPoints, origin));
return p; return p;
} }
...@@ -223,40 +231,38 @@ boost::shared_ptr<XdmfGridRegular> XdmfGridRegular::New(const double brickSizeX, ...@@ -223,40 +231,38 @@ boost::shared_ptr<XdmfGridRegular> XdmfGridRegular::New(const double brickSizeX,
const unsigned int numPointsX, const unsigned int numPointsY, const unsigned int numPointsZ, const unsigned int numPointsX, const unsigned int numPointsY, const unsigned int numPointsZ,
const double originX, const double originY, const double originZ) const double originX, const double originY, const double originZ)
{ {
boost::shared_ptr<XdmfGridRegular> p(new XdmfGridRegular(brickSizeX, brickSizeY, brickSizeZ, numPointsX, numPointsY, numPointsZ, originX, originY, originZ));