ENH: Modify XdmfArray to have a std::vector like interface except for inset,...

ENH: Modify XdmfArray to have a std::vector like interface except for inset, which is replaced in XdmfArray with copyValues (for name clarity and ability to stride)
Modify tests to use new functions
Significantly modify swig python wrapping to easily store values from python lists in XdmfArrays.
parent 91cfecb9
......@@ -61,24 +61,81 @@ namespace boost {
%include XdmfTopology.hpp
%include XdmfTopologyType.hpp
%template(CharVector) std::vector<char>;
%template(ShortVector) std::vector<short>;
%template(IntVector) std::vector<int>;
%template(LongVector) std::vector<long>;
%template(FloatVector) std::vector<float>;
%template(DoubleVector) std::vector<double>;
%template(UCharVector) std::vector<unsigned char>;
%template(UShortVector) std::vector<unsigned short>;
%template(UIntVector) std::vector<unsigned int>;
// Provide accessors from python lists to XdmfArrays
%extend XdmfArray {
%template(copyValues) copyValues<char>;
%template(copyValues) copyValues<short>;
%template(copyValues) copyValues<int>;
%template(copyValues) copyValues<long>;
%template(copyValues) copyValues<float>;
%template(copyValues) copyValues<double>;
%template(copyValues) copyValues<unsigned char>;
%template(copyValues) copyValues<unsigned short>;
%template(copyValues) copyValues<unsigned int>;
void copyValueAsChar(int index, char value) {
$self->copyValues(index, &value);
}
void copyValueAsShort(int index, short value) {
$self->copyValues(index, &value);
}
void copyValueAsInt(int index, int value) {
$self->copyValues(index, &value);
}
void copyValueAsLong(int index, long value) {
$self->copyValues(index, &value);
}
void copyValueAsFloat(int index, float value) {
$self->copyValues(index, &value);
}
void copyValueAsDouble(int index, double value) {
$self->copyValues(index, &value);
}
void copyValueAsUChar(int index, unsigned char value) {
$self->copyValues(index, &value);
}
void copyValueAsUShort(int index, unsigned short value) {
$self->copyValues(index, &value);
}
void copyValueAsUInt(int index, unsigned int value) {
$self->copyValues(index, &value);
}
};
%extend boost::shared_ptr<XdmfArray> {
%pythoncode {
def copyValuesAsChar(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsChar(i+startIndex, values[i])
def copyValuesAsShort(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsShort(i+startIndex, values[i])
def copyValuesAsInt(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsInt(i+startIndex, values[i])
def copyValuesAsLong(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsLong(i+startIndex, values[i])
def copyValuesAsFloat(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsFloat(i+startIndex, values[i])
def copyValuesAsDouble(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsDouble(i+startIndex, values[i])
def copyValuesAsUChar(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsUChar(i+startIndex, values[i])
def copyValuesAsUShort(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsUShort(i+startIndex, values[i])
def copyValuesAsUInt(self, startIndex, values):
for i in range(0, len(values)):
self.copyValueAsUInt(i+startIndex, values[i])
};
};
This diff is collapsed.
......@@ -9,53 +9,104 @@
#include "XdmfVisitor.hpp"
#include <sstream>
class XdmfArrayClear : public boost::static_visitor <void> {
public:
XdmfArrayClear()
{
}
template<typename T> void operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return array->clear();
}
};
class XdmfArrayCopyArrayValues : public boost::static_visitor <void> {
public:
XdmfArrayCopyArrayValues(int startIndex, int valuesStartIndex, int numValues, int arrayStride, int valuesStride) :
mStartIndex(startIndex),
mValuesStartIndex(valuesStartIndex),
mNumValues(numValues),
mArrayStride(arrayStride),
mValuesStride(valuesStride)
{
}
template<typename T, typename U> void operator()(const boost::shared_ptr<std::vector<T> > & array, const boost::shared_ptr<std::vector<U> > & arrayToCopy) const
{
int size = mStartIndex + mNumValues;
if(mArrayStride > 1)
{
size = mStartIndex + mNumValues * mArrayStride - 1;
}
if(array->size() < size)
{
array->resize(size);
}
for(int i=0; i<mNumValues; ++i)
{
array->operator[](mStartIndex + i*mArrayStride) = (T)arrayToCopy->operator[](mValuesStartIndex + i*mValuesStride);
}
}
private:
int mStartIndex;
int mValuesStartIndex;
int mNumValues;
int mArrayStride;
int mValuesStride;
};
class XdmfArrayGetHDF5Type : public boost::static_visitor <hid_t> {
public:
XdmfArrayGetHDF5Type()
{
}
hid_t operator()(const boost::shared_ptr<std::vector<char> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<char> > & array) const
{
return H5T_NATIVE_CHAR;
}
hid_t operator()(const boost::shared_ptr<std::vector<short> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<short> > & array) const
{
return H5T_NATIVE_SHORT;
}
hid_t operator()(const boost::shared_ptr<std::vector<int> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<int> > & array) const
{
return H5T_NATIVE_INT;
}
hid_t operator()(const boost::shared_ptr<std::vector<long> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<long> > & array) const
{
return H5T_NATIVE_LONG;
}
hid_t operator()(const boost::shared_ptr<std::vector<float> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<float> > & array) const
{
return H5T_NATIVE_FLOAT;
}
hid_t operator()(const boost::shared_ptr<std::vector<double> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<double> > & array) const
{
return H5T_NATIVE_DOUBLE;
}
hid_t operator()(const boost::shared_ptr<std::vector<unsigned char> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<unsigned char> > & array) const
{
return H5T_NATIVE_UCHAR;
}
hid_t operator()(const boost::shared_ptr<std::vector<unsigned short> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<unsigned short> > & array) const
{
return H5T_NATIVE_USHORT;
}
hid_t operator()(const boost::shared_ptr<std::vector<unsigned int> > array) const
hid_t operator()(const boost::shared_ptr<std::vector<unsigned int> > & array) const
{
return H5T_NATIVE_UINT;
}
......@@ -67,47 +118,47 @@ public:
{
}
int operator()(const boost::shared_ptr<std::vector<char> > array) const
int operator()(const boost::shared_ptr<std::vector<char> > & array) const
{
return 1;
}
int operator()(const boost::shared_ptr<std::vector<short> > array) const
int operator()(const boost::shared_ptr<std::vector<short> > & array) const
{
return 2;
}
int operator()(const boost::shared_ptr<std::vector<int> > array) const
int operator()(const boost::shared_ptr<std::vector<int> > & array) const
{
return 4;
}
int operator()(const boost::shared_ptr<std::vector<long> > array) const
int operator()(const boost::shared_ptr<std::vector<long> > & array) const
{
return 8;
}
int operator()(const boost::shared_ptr<std::vector<float> > array) const
int operator()(const boost::shared_ptr<std::vector<float> > & array) const
{
return 4;
}
int operator()(const boost::shared_ptr<std::vector<double> > array) const
int operator()(const boost::shared_ptr<std::vector<double> > & array) const
{
return 8;
}
int operator()(const boost::shared_ptr<std::vector<unsigned char> > array) const
int operator()(const boost::shared_ptr<std::vector<unsigned char> > & array) const
{
return 1;
}
int operator()(const boost::shared_ptr<std::vector<unsigned short> > array) const
int operator()(const boost::shared_ptr<std::vector<unsigned short> > & array) const
{
return 2;
}
int operator()(const boost::shared_ptr<std::vector<unsigned int> > array) const
int operator()(const boost::shared_ptr<std::vector<unsigned int> > & array) const
{
return 4;
}
......@@ -119,47 +170,47 @@ public:
{
}
std::string operator()(const boost::shared_ptr<std::vector<char> > array) const
std::string operator()(const boost::shared_ptr<std::vector<char> > & array) const
{
return "Char";
}
std::string operator()(const boost::shared_ptr<std::vector<short> > array) const
std::string operator()(const boost::shared_ptr<std::vector<short> > & array) const
{
return "Short";
}
std::string operator()(const boost::shared_ptr<std::vector<int> > array) const
std::string operator()(const boost::shared_ptr<std::vector<int> > & array) const
{
return "Int";
}
std::string operator()(const boost::shared_ptr<std::vector<long> > array) const
std::string operator()(const boost::shared_ptr<std::vector<long> > & array) const
{
return "Int";
}
std::string operator()(const boost::shared_ptr<std::vector<float> > array) const
std::string operator()(const boost::shared_ptr<std::vector<float> > & array) const
{
return "Float";
}
std::string operator()(const boost::shared_ptr<std::vector<double> > array) const
std::string operator()(const boost::shared_ptr<std::vector<double> > & array) const
{
return "Float";
}
std::string operator()(const boost::shared_ptr<std::vector<unsigned char> > array) const
std::string operator()(const boost::shared_ptr<std::vector<unsigned char> > & array) const
{
return "UChar";
}
std::string operator()(const boost::shared_ptr<std::vector<unsigned short> > array) const
std::string operator()(const boost::shared_ptr<std::vector<unsigned short> > & array) const
{
return "UShort";
}
std::string operator()(const boost::shared_ptr<std::vector<unsigned int> > array) const
std::string operator()(const boost::shared_ptr<std::vector<unsigned int> > & array) const
{
return "UInt";
}
......@@ -172,7 +223,7 @@ public:
{
}
template<typename T> int operator()(const boost::shared_ptr<std::vector<T> > array) const
template<typename T> int operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return array->size();
}
......@@ -185,7 +236,7 @@ public:
{
}
template<typename T> const void* const operator()(const boost::shared_ptr<std::vector<T> > array) const
template<typename T> const void* const operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return &array->operator[](0);
}
......@@ -198,7 +249,7 @@ public:
{
}
std::string operator()(const boost::shared_ptr<std::vector<char> > array) const
std::string operator()(const boost::shared_ptr<std::vector<char> > & array) const
{
std::stringstream toReturn;
for(int i=0; i<array->size(); ++i)
......@@ -208,7 +259,7 @@ public:
return toReturn.str();
}
template<typename T> std::string operator()(const boost::shared_ptr<std::vector<T> > array) const
template<typename T> std::string operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
std::stringstream toReturn;
for(int i=0; i<array->size(); ++i)
......@@ -219,6 +270,20 @@ public:
}
};
class XdmfArrayNewArray : public boost::static_visitor <void> {
public:
XdmfArrayNewArray()
{
}
template<typename T> void operator()(boost::shared_ptr<std::vector<T> > & array) const
{
boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>());
array = newArray;
}
};
XdmfArray::XdmfArray() :
mInitialized(false)
{
......@@ -230,6 +295,28 @@ XdmfArray::~XdmfArray()
std::cout << "Deleted Array " << this << std::endl;
}
void XdmfArray::copyValues(int startIndex, boost::shared_ptr<XdmfArray> values, int valuesStartIndex, int numValues, int arrayStride, int valuesStride)
{
if(!mInitialized)
{
// Copy the values variant in order to get the type (only taking smart pointer so no worries about large copies)
mArray = values->getVariant();
// Reinitialize variant array to contain new array with same type.
boost::apply_visitor( XdmfArrayNewArray(), mArray);
//boost::shared_ptr<std::vector<double> > newArray(new std::vector<double>());
//mArray = newArray;
//std::cout << boost::get<boost::shared_ptr<std::vector<double> > >(mArray)->operator[](0) << std::endl;
//std::cout << this->getValuesString() << std::endl;
}
boost::apply_visitor( XdmfArrayCopyArrayValues(startIndex, valuesStartIndex, numValues, arrayStride, valuesStride), mArray, values->getVariant());
}
void XdmfArray::clear()
{
return boost::apply_visitor( XdmfArrayClear(), mArray);
}
hid_t XdmfArray::getHDF5Type() const
{
return boost::apply_visitor( XdmfArrayGetHDF5Type(), mArray);
......@@ -250,11 +337,6 @@ std::string XdmfArray::getType() const
return boost::apply_visitor( XdmfArrayGetType(), mArray);
}
//const boost::shared_ptr<std::vector<void> > getValues() const
//{
//return boost::apply_visitor( XdmfArrayGetValues(), mArray);
//}
const void* const XdmfArray::getValuesPointer() const
{
return boost::apply_visitor( XdmfArrayGetValuesPointer(), mArray);
......
......@@ -14,31 +14,11 @@
#include <hdf5.h>
#include <vector>
template <typename T>
class XdmfArrayGetValues : public boost::static_visitor <boost::shared_ptr<std::vector<T> > > {
public:
XdmfArrayGetValues()
{
}
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<T> > array) const
{
return array;
}
template <typename U>
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<U> > array) const
{
return boost::shared_ptr<std::vector<T> >();
}
};
template<typename T>
class XdmfArraySetValues : public boost::static_visitor <void> {
class XdmfArrayCopyValues : public boost::static_visitor <void> {
public:
XdmfArraySetValues(int startIndex, T* valuesPointer, int numValues, int arrayStride = 1, int valuesStride = 1) :
XdmfArrayCopyValues(int startIndex, T* valuesPointer, int numValues = 1, int arrayStride = 1, int valuesStride = 1) :
mStartIndex(startIndex),
mValuesPointer(valuesPointer),
mNumValues(numValues),
......@@ -73,21 +53,87 @@ private:
int mValuesStride;
};
template <typename T>
class XdmfArrayGetValues : public boost::static_visitor <boost::shared_ptr<std::vector<T> > > {
public:
XdmfArrayGetValues()
{
}
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<T> > array) const
{
return array;
}
template <typename U>
boost::shared_ptr<std::vector<T> > operator()(const boost::shared_ptr<std::vector<U> > array) const
{
return boost::shared_ptr<std::vector<T> >();
}
};
template <typename T>
class XdmfArrayGetValuesConst : public boost::static_visitor <const boost::shared_ptr<const std::vector<T> > > {
public:
XdmfArrayGetValuesConst()
{
}
const boost::shared_ptr<const std::vector<T> > operator()(const boost::shared_ptr<const std::vector<T> > array) const
{
return array;
}
template <typename U>
const boost::shared_ptr<const std::vector<T> > operator()(const boost::shared_ptr<const std::vector<U> > array) const
{
return boost::shared_ptr<std::vector<T> >();
}
};
class XdmfArray : public XdmfItem {
public:
XdmfNewMacro(XdmfArray);
/**
* Copy the values from a vector into this array
* Copy values from an XdmfArray into this array.
*
* @param array the vector to copy into this array.
* @param startIndex the index in this array to begin insertion.
* @param values a shared pointer to an XdmfArray to copy into this array.
* @param numValues the number of values to copy into this array.
* @param arrayStride number of values to stride in this array between each copy.
* @param valuesStride number of values to stride in the XdmfArray between each copy.
*/
template<typename T> void copyValues(std::vector<T> & array)
{
boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>(array));
mArray = newArray;
}
void copyValues(int startIndex, boost::shared_ptr<XdmfArray> values, int valuesStartIndex= 0, int numValues = 1, int arrayStride = 1, int valuesStride = 1);
/**
* Copy values from an array into this array.
*
* @param startIndex the index in this array to begin insertion.
* @param valuesPointer a pointer to the values to copy into this array.
* @param numValues the number of values to copy into this array.
* @param arrayStride number of values to stride in this array between each copy.
* @param valuesStride number of values to stride in the pointer between each copy.
*/
template<typename T> void copyValues(int startIndex, T* valuesPointer, int numValues = 1, int arrayStride = 1, int valuesStride = 1)
{
if(!mInitialized)
{
// Set type of variant to type of pointer
boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>());
mArray = newArray;
mInitialized = true;
}
boost::apply_visitor( XdmfArrayCopyValues<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray);
}
/**
* Clears all values from this array
*/
virtual void clear();
/**
* Get the data type of this array.
......@@ -134,7 +180,11 @@ public:
*
* @return a smart pointer to the internal vector of values stored in this array
*/
//virtual const boost::shared_ptr<std::vector<void> > getValues() const;
template <typename T>
const boost::shared_ptr<const std::vector<T> > getValues() const
{
return boost::apply_visitor( XdmfArrayGetValuesConst<T>(), mArray);
}
/**
* Get a pointer to the values stored in this array (const version).
......@@ -150,27 +200,6 @@ public:
*/
virtual std::string getValuesString() const;
/**
* Insert the values from a pointer into this array.
*
* @param startIndex the index in this array to begin insertion.
* @param valuesPointer a pointer to the values to copy into this array.
* @param numValues the number of values to copy into this array.
* @param arrayStride number of values to stride in this array between each copy.
* @param valuesStride number of values to stride in the pointer between each copy.
*/
template<typename T> void insertValues(int startIndex, T* valuesPointer, int numValues = 1, int arrayStride = 1, int valuesStride = 1)
{
if(!mInitialized)
{
// Set type of variant to type of pointer
boost::shared_ptr<std::vector<T> > newArray(new std::vector<T>());
mArray = newArray;
mInitialized = true;
}
boost::apply_visitor( XdmfArraySetValues<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray);
}
virtual std::string printSelf() const;
/**
......@@ -193,17 +222,24 @@ protected:
private:
bool mInitialized;
typedef boost::variant<
boost::shared_ptr<std::vector<char> >,
boost::shared_ptr<std::vector<short> >,
boost::shared_ptr<std::vector<int> >,
boost::shared_ptr<std::vector<long> >,
boost::shared_ptr<std::vector<float> >,
boost::shared_ptr<std::vector<double> >,
boost::shared_ptr<std::vector<unsigned char> >,
boost::shared_ptr<std::vector<unsigned short> >,
boost::shared_ptr<std::vector<unsigned int> > > ArrayVariant;
const ArrayVariant getVariant() const
{
return mArray;
}
boost::variant<boost::shared_ptr<std::vector<char> >,
boost::shared_ptr<std::vector<short> >,
boost::shared_ptr<std::vector<int> >,
boost::shared_ptr<std::vector<long> >,
boost::shared_ptr<std::vector<float> >,
boost::shared_ptr<std::vector<double> >,
boost::shared_ptr<std::vector<unsigned char> >,
boost::shared_ptr<std::vector<unsigned short> >,
boost::shared_ptr<std::vector<unsigned int> > > mArray;
ArrayVariant mArray;
bool mInitialized;
};
#endif /* XDMFARRAY_HPP_ */
This diff is collapsed.
......@@ -4,11 +4,11 @@ int main(int argc, char* argv[])
{
/**
* Test simple copy from array
* Copy from array
*/
double values[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
boost::shared_ptr<XdmfArray> array = XdmfArray::New();
array->insertValues(0, &values[0], 9);
array->copyValues(0, &values[0], 9);
assert(array->getSize() == 9);
assert(array->getType().compare("Float") == 0);
assert(array->getPrecision() == 8);
......@@ -25,13 +25,13 @@ int main(int argc, char* argv[])
assert(array->getValuesString().compare("1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 ") == 0);
/**
* Test simple copy from vector
* Copy from vector
*/
std::vector<int> values2;
values2.push_back(100);
values2.push_back(200);
boost::shared_ptr<XdmfArray> array2 = XdmfArray::New();
array2->copyValues(values2);
array2->copyValues(0, &values2[0], 2);
assert(array2->getSize() == 2);
assert(array2->getType().compare("Int") == 0);
assert(array2->getPrecision() == 4);
......@@ -51,7 +51,7 @@ int main(int argc, char* argv[])
assert(array2->getValuesString().compare("100 200 ") == 0);
/**
* Test shared vector assignment
* Shared vector assignment
*/
boost::shared_ptr<std::vector<char> > values3(new std::vector<char>());
values3->push_back(-2);
......@@ -77,5 +77,20 @@ int main(int argc, char* argv[])
boost::shared_ptr<std::vector<int> > storedValues3Int = array3->getValues<int>();
assert(storedValues3Int == NULL);
/**
* Copy values from another XdmfArray
*/
boost::shared_ptr<XdmfArray> array4 = XdmfArray::New();
array4->copyValues(0, array, 1, 4);
assert(array4->getSize() == 4);
assert(array4->getType().compare("Float") == 0);
assert(array4->getPrecision() == 8);
boost::shared_ptr<std::vector<double> > storedValues4 = array4->getValues<double>();
i = 1;
for(std::vector<double>::const_iterator iter = storedValues4->begin(); iter!= storedValues4->end(); ++iter, ++i)
{
assert((*iter) == storedValues->operator[](i));
}
return 0;
}
......@@ -18,12 +18,12 @@ int main(int argc, char* argv[])
double points[] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1,
0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1};
grid->getGeometry()->setGeometryType(XdmfGeometryType::XYZ());
grid->getGeometry()->getArray()->insertValues(0, &points[0], 36);
grid->getGeometry()->getArray()->copyValues(0, &points[0], 36);
// Set Topology
int connectivity[] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
grid->getTopology()->setTopologyType(XdmfTopologyType::Hexahedron());
grid->getTopology()->getArray()->insertValues(0, &connectivity[0], 16);
grid->getTopology()->getArray()->copyValues(0, &connectivity[0], 16);
// Add Node Attribute
boost::shared_ptr<XdmfAttribute> nodalAttribute = XdmfAttribute::New();
......@@ -31,7 +31,7 @@ int main(int argc, char* argv[])
nodalAttribute->setName("Nodal Attribute");
nodalAttribute->setAttributeType(XdmfAttributeType::Scalar());
nodalAttribute->setAttributeCenter(XdmfAttributeCenter::Node());
nodalAttribute->getArray()->insertValues(0, &nodeValues[0], 12);
nodalAttribute->getArray()->copyValues(0, &nodeValues[0], 12);
// Add Cell Attribute
boost::shared_ptr<XdmfAttribute> cellAttribute = XdmfAttribute::New();
......@@ -39,7 +39,7 @@ int main(int argc, char* argv[])
cellAttribute->setName("Cell Attribute");
cellAttribute->setAttributeType(XdmfAttributeType::Scalar());
cellAttribute->setAttributeCenter(XdmfAttributeCenter::Cell());
cellAttribute->getArray()->insertValues(0, &cellValues[0], 2);
cellAttribute->getArray()->copyValues(0, &cellValues[0], 2);
grid->insert(nodalAttribute);
grid->insert(cellAttribute);
......
......@@ -4,10 +4,66 @@ if __name__ == "__main__":