Commit 4157e301 authored by Ken Leiter (Civ ARL/CISD) kleiter's avatar Ken Leiter (Civ ARL/CISD) kleiter

Merge branch 'XdmfArraySmartPointer'

Conflicts:
	Xdmf.py
	XdmfPython.cpp
parents 6cde700a 8d06285b
......@@ -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(setValues) setValues<char>;
%template(setValues) setValues<short>;
%template(setValues) setValues<int>;
%template(setValues) setValues<long>;
%template(setValues) setValues<float>;
%template(setValues) setValues<double>;
%template(setValues) setValues<unsigned char>;
%template(setValues) setValues<unsigned short>;
%template(setValues) setValues<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.
This diff is collapsed.
......@@ -15,10 +15,10 @@
#include <vector>
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),
......@@ -27,20 +27,20 @@ public:
{
}
template<typename U> void operator()(std::vector<U> & array) const
template<typename U> void operator()(boost::shared_ptr<std::vector<U> > array) const
{
int size = mStartIndex + mNumValues;
if(mArrayStride > 1)
{
size = mStartIndex + mNumValues * mArrayStride - 1;
}
if(array.size() < size)
if(array->size() < size)
{
array.resize(size);
array->resize(size);
}
for(int i=0; i<mNumValues; ++i)
{
array[mStartIndex + i*mArrayStride] = (U)mValuesPointer[i*mValuesStride];
array->operator[](mStartIndex + i*mArrayStride) = (U)mValuesPointer[i*mValuesStride];
}
}
......@@ -53,11 +53,88 @@ 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 values from an XdmfArray 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.
*/
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.
*
......@@ -88,18 +165,26 @@ public:
virtual int getSize() const;
/**
* Get the values stored in this array as a string.
* Get a smart pointer to the values stored in this array
*
* @return a string containing the contents of the array.
* @return a smart pointer to the internal vector of values stored in this array
*/
virtual std::string getValues() const;
template <typename T>
boost::shared_ptr<std::vector<T> > getValues()
{
return boost::apply_visitor( XdmfArrayGetValues<T>(), mArray);
}
/**
* Get a pointer to the values stored in this array.
* Get a smart pointer to the values stored in this array (const version)
*
* @return a void pointer to the first value stored in this array.
* @return a smart pointer to the internal vector of values stored in this array
*/
virtual void* getValuesPointer();
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).
......@@ -108,34 +193,22 @@ public:
*/
virtual const void* const getValuesPointer() const;
virtual std::string printSelf() const;
/**
* Copy the values from a pointer into this array.
* Get the values stored in this array as a string.
*
* @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.
* @return a string containing the contents of the array.
*/
template<typename T> void setValues(int startIndex, T* valuesPointer, int numValues = 1, int arrayStride = 1, int valuesStride = 1)
{
if(!mInitialized)
{
// Set type of variant to type of pointer
mArray = std::vector<T>();
mInitialized = true;
}
boost::apply_visitor( XdmfArraySetValues<T>(startIndex, valuesPointer, numValues, arrayStride, valuesStride), mArray);
}
virtual std::string getValuesString() const;
virtual std::string printSelf() const;
/**
* Copy the values from a vector into this array
* Sets the values of this array to the values stored in the vector. No copy is made. This array shares ownership with
* other references to the smart pointer.
*
* @param array the vector to copy into this array.
* @param a smart pointer to a vector to store in this array.
*/
template<typename T> void setValues(std::vector<T> & array)
template<typename T> void setValues(boost::shared_ptr<std::vector<T> > array)
{
mArray = array;
}
......@@ -149,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<std::vector<char>,
std::vector<short>,
std::vector<int>,
std::vector<long>,
std::vector<float>,
std::vector<double>,
std::vector<unsigned char>,
std::vector<unsigned short>,
std::vector<unsigned int> > mArray;
ArrayVariant mArray;
bool mInitialized;
};
#endif /* XDMFARRAY_HPP_ */
This diff is collapsed.
......@@ -103,7 +103,7 @@ void XdmfVisitor::visit(const XdmfArray * const array, boost::shared_ptr<XdmfVis
}
else
{
xmlTextValues << array->getValues();
xmlTextValues << array->getValuesString();
}
xmlAddChild(xmlCurrentNode, xmlNewText((xmlChar*)xmlTextValues.str().c_str()));
......
......@@ -3,52 +3,93 @@
int main(int argc, char* argv[])
{
/**
* 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();
std::vector<char> values;
values.push_back(1);
values.push_back(2);
values.push_back(3);
values.push_back(4);
array->setValues(0, &values[0], 4, 1, 1);
std::cout << array->getValues() << std::endl;
std::cout << array->getType() << std::endl;
array->copyValues(0, &values[0], 9);
assert(array->getSize() == 9);
assert(array->getType().compare("Float") == 0);
assert(array->getPrecision() == 8);
assert(array->getValuesString().compare("1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 ") == 0);
// Assert we copied values correctly
boost::shared_ptr<std::vector<double> > storedValues = array->getValues<double>();
int i = 0;
for(std::vector<double>::const_iterator iter = storedValues->begin(); iter!= storedValues->end(); ++iter, ++i)
{
assert(*iter == values[i]);
}
// Now modify original array
values[0] = 0;
assert(array->getValuesString().compare("1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 ") == 0);
boost::shared_ptr<XdmfArray> array2 = XdmfArray::New();
/**
* Copy from vector
*/
std::vector<int> values2;
values2.push_back(100);
values2.push_back(200);
array2->setValues(0, &values2[0], 2, 1, 1);
std::cout << array2->getValues() << std::endl;
std::cout << array2->getType() << std::endl;
array2->setValues(2, &values[0], 2, 1, 1);
std::cout << array2->getValues() << std::endl;
std::cout << array2->getType() << std::endl;
boost::shared_ptr<XdmfArray> array3 = XdmfArray::New();
double values3[] = {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};
array3->setValues(0, &values3[0], 36);
std::cout << array3->getValues() << std::endl;
std::cout << array3->getType() << std::endl;
const double* const array3Pointer = (const double* const)array3->getValuesPointer();
for(int i=0; i<array3->getSize(); ++i)
boost::shared_ptr<XdmfArray> array2 = XdmfArray::New();
array2->copyValues(0, &values2[0], 2);
assert(array2->getSize() == 2);
assert(array2->getType().compare("Int") == 0);
assert(array2->getPrecision() == 4);
assert(array2->getValuesString().compare("100 200 ") == 0);
// Assert we copied values correctly
boost::shared_ptr<std::vector<int> > storedValues2 = array2->getValues<int>();
i = 0;
for(std::vector<int>::const_iterator iter = storedValues2->begin(); iter!= storedValues2->end(); ++iter, ++i)
{
assert(array3Pointer[i] == values3[i]);
assert(*iter == values2[i]);
}
// Now modify original array
values2.push_back(300);
assert(array2->getSize() == 2);
assert(array2->getType().compare("Int") == 0);
assert(array2->getPrecision() == 4);
assert(array2->getValuesString().compare("100 200 ") == 0);
boost::shared_ptr<XdmfArray> array4 = XdmfArray::New();
std::vector<long> values4;
for(int i=1000; i<1100; ++i)
{
values4.push_back(i);
}
array4->setValues(values4);
/**
* Shared vector assignment
*/
boost::shared_ptr<std::vector<char> > values3(new std::vector<char>());
values3->push_back(-2);
values3->push_back(-1);
values3->push_back(0);
values3->push_back(1);
values3->push_back(2);
boost::shared_ptr<XdmfArray> array3 = XdmfArray::New();
array3->setValues(values3);
assert(array3->getSize() == 5);
assert(array3->getType().compare("Char") == 0);
assert(array3->getPrecision() == 1);
assert(array3->getValuesString().compare("-2 -1 0 1 2 ") == 0);
// Now modify original array
values3->push_back(8);
assert(array3->getSize() == 6);
assert(array3->getValuesString().compare("-2 -1 0 1 2 8 ") == 0);
// Assert we have the same values!
boost::shared_ptr<std::vector<char> > storedValues3 = array3->getValues<char>();
assert(storedValues3 == values3);
// Assert that we can't get a smart pointer to an int vector
boost::shared_ptr<std::vector<int> > storedValues3Int = array3->getValues<int>();
assert(storedValues3Int == NULL);
const long* const array4Pointer = (const long* const)array4->getValuesPointer();
for(int i=0; i<array4->getSize(); ++i)
/**
* 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(array4Pointer[i] == values4[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()->setValues(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()->setValues(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()->setValues(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()->setValues(0, &cellValues[0], 2);
cellAttribute->getArray()->copyValues(0, &cellValues[0], 2);
grid->insert(nodalAttribute);
grid->insert(cellAttribute);
......
......@@ -4,10 +4,66 @@ if __name__ == "__main__":
values1 = [0, 1, 2, 3]
array1 = XdmfArray.New()
array1.setValues(IntVector(values1))
print array1.getValues()
print array1.getType()
array1.copyValuesAsChar(0, values1)
print array1.getValuesString()
print array1.getType() + " " + str(array1.getPrecision())
assert array1.getType() == "Char"
assert array1.getPrecision() == 1
array1.setValues(IntVector(values1[0:2]))
print array1.getValues()
print array1.getType()
array2 = XdmfArray.New()
array2.copyValuesAsShort(0, values1)
print array2.getValuesString()
print array2.getType() + " " + str(array2.getPrecision())
assert array2.getType() == "Short"
assert array2.getPrecision() == 2
array3 = XdmfArray.New()
array3.copyValuesAsInt(0, values1[2:4])
print array3.getValuesString()
print array3.getType() + " " + str(array3.getPrecision())
assert array3.getType() == "Int"
assert array3.getPrecision() == 4
# Stride
array4 = XdmfArray.New()
array4.copyValuesAsLong(0, values1[0:4:2])
print array4.getValuesString()
print array4.getType() + " " + str(array4.getPrecision())
assert array4.getType() == "Int"
assert array4.getPrecision() == 8
# Reverse
array5 = XdmfArray.New()
array5.copyValuesAsFloat(0, values1[::-1])
print array5.getValuesString()
print array5.getType() + " " + str(array5.getPrecision())
assert array5.getType() == "Float"
assert array5.getPrecision() == 4
array6 = XdmfArray.New()
array6.copyValuesAsDouble(0, values1)
print array6.getValuesString()
print array6.getType() + " " + str(array6.getPrecision())
assert array6.getType() == "Float"
assert array6.getPrecision() == 8
array7 = XdmfArray.New()
array7.copyValuesAsUChar(0, values1)
print array7.getValuesString()
print array7.getType() + " " + str(array7.getPrecision())
assert array7.getType() == "UChar"
assert array7.getPrecision() == 1
array8 = XdmfArray.New()
array8.copyValuesAsUShort(0, values1)
print array8.getValuesString()
print array8.getType() + " " + str(array8.getPrecision())
assert array8.getType() == "UShort"
assert array8.getPrecision() == 2
array9 = XdmfArray.New()
array9.copyValuesAsUInt(0, values1)
print array9.getValuesString()
print array9.getType() + " " + str(array9.getPrecision())
assert array9.getType() == "UInt"
assert array9.getPrecision() == 4
......@@ -11,25 +11,25 @@ if __name__ == "__main__":
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().setValues(DoubleVector(points))
grid.getGeometry().getArray().copyValuesAsDouble(0, points)
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().setValues(IntVector(connectivity))
grid.getTopology().getArray().copyValuesAsInt(0, connectivity)
nodalAttribute = XdmfAttribute.New()
nodalAttribute.setName("Nodal Attribute")
nodalAttribute.setAttributeType(XdmfAttributeType.Scalar())
nodalAttribute.setAttributeCenter(XdmfAttributeCenter.Node())
nodeVals = [100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600, 700]
nodalAttribute.getArray().setValues(DoubleVector(nodeVals))
nodalAttribute.getArray().copyValuesAsDouble(0, nodeVals)
cellAttribute = XdmfAttribute.New()
cellAttribute.setName("Cell Attribute")
cellAttribute.setAttributeType(XdmfAttributeType.Scalar())
cellAttribute.setAttributeCenter(XdmfAttributeCenter.Cell())
cellVals = [100, 200]
cellAttribute.getArray().setValues(DoubleVector(cellVals))
cellAttribute.getArray().copyValuesAsDouble(0, cellVals)
grid.insert(nodalAttribute)
grid.insert(cellAttribute)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment