Commit 5e38d232 authored by Andrew J. Burns (Cont's avatar Andrew J. Burns (Cont

Update to function code. Added error suppression.

parent dc686f86
......@@ -225,7 +225,6 @@ if(NOT XDMF_BUILD_CORE_ONLY)
XdmfAttributeType
XdmfCurvilinearGrid
XdmfDomain
XdmfFunction
XdmfGeometry
XdmfGeometryType
XdmfGraph
......
This diff is collapsed.
......@@ -228,81 +228,6 @@ XdmfItemFactory::createItem(const std::string & itemTag,
}
return XdmfTopology::New();
}
else if (itemTag.compare(XdmfFunction::ItemTag) == 0) {
std::map<std::string, std::string>::const_iterator type =
itemProperties.find("ConstructedType");
std::string arraySubType;
if(type == itemProperties.end()) {
// If no type is specified an array is generated
arraySubType = "DataItem";
}
else {
arraySubType = type->second;
}
std::map<std::string, std::string>::const_iterator expression =
itemProperties.find("Expression");
std::string expressionToParse;
if(expression == itemProperties.end()) {
try {
XdmfError::message(XdmfError::FATAL,
"Error: Function found no expression");
}
catch (XdmfError e) {
throw e;
}
}
else {
expressionToParse = expression->second;
}
std::map<std::string, shared_ptr<XdmfArray> > variableCollection;
for (unsigned int i = 0; i < childItems.size(); ++i) {
try {
shared_ptr<XdmfArray> tempArray =
shared_dynamic_cast<XdmfArray>(childItems[i]);
variableCollection[tempArray->getName()] = tempArray;
tempArray->read();
}
catch (...) {
try {
XdmfError::message(XdmfError::FATAL,
"Error: Function passed non-Array item");
}
catch (XdmfError e) {
throw e;
}
}
}
shared_ptr<XdmfArray> parsedArray = shared_ptr<XdmfArray>();
try {
parsedArray = XdmfFunction::evaluateExpression(expressionToParse,
variableCollection);
}
catch (XdmfError e) {
throw e;
}
if (arraySubType != "DataItem") {
// The properties and children aren't really needed
// to generate the object, but the factory still requires them.
std::vector<shared_ptr<XdmfItem> > newArrayChildren;
shared_ptr<XdmfArray> returnArray = XdmfArray::New();
// This should generate an item that corresponds to the tag provided
// the casting ensures that it is a subtype of array
// Using a factory to be able to build things outside of core
returnArray = shared_dynamic_cast<XdmfArray>(createItem(
arraySubType,
itemProperties,
newArrayChildren));
returnArray->insert(0, parsedArray, 0, parsedArray->getSize());
//returnArray->setFunction();
return returnArray;
}
else {
return parsedArray;
}
}
return shared_ptr<XdmfItem>();
}
catch (XdmfError e) {
......
......@@ -96,6 +96,7 @@ set(XdmfCoreSources
XdmfCoreItemFactory
XdmfCoreReader
XdmfError
XdmfFunction
XdmfHDF5Controller
XdmfHDF5Writer
XdmfHeavyDataController
......
......@@ -30,6 +30,7 @@
#include <math.h>
#include "XdmfArray.hpp"
#include "XdmfArrayType.hpp"
#include "XdmfFunction.hpp"
#include "XdmfHDF5Controller.hpp"
#include "XdmfHeavyDataController.hpp"
#include "XdmfVisitor.hpp"
......@@ -562,7 +563,9 @@ XdmfArray::New()
XdmfArray::XdmfArray() :
mArrayPointerNumValues(0),
mName(""),
mTmpReserveSize(0)
mTmpReserveSize(0),
mWriteAsFunction(false),
mFunction(shared_ptr<XdmfFunction>())
{
}
......@@ -653,6 +656,12 @@ XdmfArray::getDimensionsString() const
dimensions.size());
}
shared_ptr<XdmfFunction>
XdmfArray::getFunction()
{
return mFunction;
}
std::map<std::string, std::string>
XdmfArray::getItemProperties() const
{
......@@ -714,6 +723,12 @@ XdmfArray::getValuesString() const
mArray);
}
bool
XdmfArray::getWriteAsFunction()
{
return mWriteAsFunction;
}
shared_ptr<XdmfHeavyDataController>
XdmfArray::getHeavyDataController()
{
......@@ -1210,6 +1225,13 @@ XdmfArray::read()
}
}
void
XdmfArray::readFunction()
{
shared_ptr<XdmfArray> tempArray = mFunction->read();
this->swap(tempArray);
}
void
XdmfArray::release()
{
......@@ -1232,6 +1254,18 @@ XdmfArray::setName(const std::string & name)
mName = name;
}
void
XdmfArray::setFunction(shared_ptr<XdmfFunction> newFunction)
{
mFunction = newFunction;
}
void
XdmfArray::setWriteAsFunction(bool newStatus)
{
mWriteAsFunction = newStatus;
}
void
XdmfArray::swap(const shared_ptr<XdmfArray> array)
{
......
......@@ -31,6 +31,7 @@ class XdmfHeavyDataController;
// Includes
#include "XdmfCore.hpp"
#include "XdmfItem.hpp"
#include "XdmfFunction.hpp"
#include <boost/shared_array.hpp>
#include <boost/variant.hpp>
......@@ -279,6 +280,36 @@ public:
*/
std::string getDimensionsString() const;
/**
* Gets the function that the array will fill from when readFunction is called
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfArray.cpp
* @skipline //#initialization
* @until //#initialization
* @skipline //#setFunction
* @until //#setFunction
* @skipline //#getFunction
* @until //#getFunction
*
*
* Python
*
* @dontinclude XdmfExampleArray.py
* @skipline #//initialization
* @until #//initialization
* @skipline #//setFunction
* @until #//setFunction
* @skipline #//getFunction
* @until #//getFunction
*
* @return The function associated with this array
*/
shared_ptr<XdmfFunction> getFunction();
std::map<std::string, std::string> getItemProperties() const;
std::string getItemTag() const;
......@@ -502,6 +533,40 @@ public:
*/
std::string getValuesString() const;
/**
* Gets if this array will be written as a function when written to file.
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfArray.cpp
* @skipline //#initialization
* @until //#initialization
* @skipline //#setFunction
* @until //#setFunction
* @skipline //#setWriteAsFunction
* @until //#setWriteAsFunction
* @skipline //#getWriteAsFunction
* @until //#getWriteAsFunction
*
*
* Python
*
* @dontinclude XdmfExampleArray.py
* @skipline #//initialization
* @until #//initialization
* @skipline #//setFunction
* @until #//setFunction
* @skipline #//setWriteAsFunction
* @until #//setWriteAsFunction
* @skipline #//getWriteAsFunction
* @until #//getWriteAsFunction
*
* @return Whether the array will be written as a function
*/
bool getWriteAsFunction();
/**
* Initialize the array to a specific size.
*
......@@ -918,6 +983,35 @@ public:
*/
void read();
/**
* Accumulates the data via the function associated with the array and
* swaps the data with the data currently in the array.
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfArray.cpp
* @skipline //#initialization
* @until //#initialization
* @skipline //#setFunction
* @until //#setFunction
* @skipline //#readFunction
* @until //#readFunction
*
*
* Python
*
* @dontinclude XdmfExampleArray.py
* @skipline #//initialization
* @until #//initialization
* @skipline #//setFunction
* @until #//setFunction
* @skipline #//readFunction
* @until #//readFunction
*/
void readFunction();
/**
* Release all data currently held in memory.
*
......@@ -1041,6 +1135,32 @@ public:
void resize(const std::vector<unsigned int> & dimensions,
const T & value = 0);
/**
* Sets the function from which the Array will fill when readFunction is called.
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfArray.cpp
* @skipline //#initialization
* @until //#initialization
* @skipline //#setFunction
* @until //#setFunction
*
*
* Python
*
* @dontinclude XdmfExampleArray.py
* @skipline #//initialization
* @until #//initialization
* @skipline #//setFunction
* @until #//setFunction
*
* @param newFunction The function to be associated with this array
*/
void setFunction(shared_ptr<XdmfFunction> newFunction);
/**
* Set the name of the array.
*
......@@ -1160,6 +1280,36 @@ public:
template<typename T>
void setValuesInternal(const shared_ptr<std::vector<T> > array);
/**
* Sets whether the array will be written as a function when written to file.
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfArray.cpp
* @skipline //#initialization
* @until //#initialization
* @skipline //#setFunction
* @until //#setFunction
* @skipline //#setWriteAsFunction
* @until //#setWriteAsFunction
*
*
* Python
*
* @dontinclude XdmfExampleArray.py
* @skipline #//initialization
* @until #//initialization
* @skipline #//setFunction
* @until #//setFunction
* @skipline #//setWriteAsFunction
* @until #//setWriteAsFunction
*
* @param newStatus Whether the array will be set to be written as a function
*/
void setWriteAsFunction(bool newStatus = false);
/**
* Exchange the contents of the vector with the contents of this
* array. No copy is made. The internal arrays are swapped.
......@@ -1308,6 +1458,8 @@ private:
std::vector<unsigned int> mDimensions;
std::string mName;
unsigned int mTmpReserveSize;
bool mWriteAsFunction;
shared_ptr<XdmfFunction> mFunction;
};
......
......@@ -20,6 +20,7 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
#include <XdmfDSMBuffer.hpp>
#include <XdmfDSMCommMPI.hpp>
#include <XdmfError.hpp>
#include <XdmfFunction.hpp>
#include <XdmfHeavyDataController.hpp>
#include <XdmfHeavyDataWriter.hpp>
#include <XdmfHDF5Controller.hpp>
......@@ -50,6 +51,7 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
#include <XdmfCoreItemFactory.hpp>
#include <XdmfCoreReader.hpp>
#include <XdmfError.hpp>
#include <XdmfFunction.hpp>
#include <XdmfHeavyDataController.hpp>
#include <XdmfHeavyDataWriter.hpp>
#include <XdmfHDF5Controller.hpp>
......@@ -318,7 +320,6 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
}
}
static shared_ptr<XdmfArray> XdmfArrayPtr(PyObject * obj)
{
void * resultPointer = 0;
......@@ -328,9 +329,6 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
return returnArray;
}
};
%extend XdmfArrayType {
......@@ -339,6 +337,120 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
}
};
/*This causes it to avoid throwing a warning for redefining fuctions that are defined for XdmfArray.
I do this because doing so was intentional.*/
#pragma SWIG nowarn=302
/*Warnint 325 is due to having nested classes in XdmfFunction that are not accessible when wrapped.
As of right now, this is acceptable behavior. So, the warning is suppressed*/
#pragma SWIG nowarn=325
%extend XdmfFunction {
%{
/*trying to transfer python functions*/
/*note, accessing private members is impossible from swig.*/
class PythonFunction : public XdmfFunction::XdmfFunctionInternal {
public:
static shared_ptr<PythonFunction>
New(PyObject * functionref)
{
shared_ptr<PythonFunction> p (new PythonFunction(functionref));
return p;
}
~PythonFunction()
{
}
virtual shared_ptr<XdmfArray> execute(std::vector<shared_ptr<XdmfArray> > valueVector)
{
swig_type_info * paramType = SWIG_TypeQuery("_p_std__vectorT_boost__shared_ptrT_XdmfArray_t_std__allocatorT_boost__shared_ptrT_XdmfArray_t_t_t");
PyObject * pyVector = SWIG_NewPointerObj(static_cast<void*>(& valueVector), paramType, SWIG_POINTER_NEW);
PyObject * args = PyTuple_New(1);
/* In this case you could also cast a pointer to the vector into the PyObject * type, but that doesn't work for all types*/
PyTuple_SetItem(args, 0, pyVector);
PyObject * resultObject = PyObject_CallObject(mInternalFunction, args);
void * resultPointer = 0;
swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
SWIG_ConvertPtr(resultObject, &resultPointer, returnType, 0);
shared_ptr<XdmfArray> * returnArrayPointer = reinterpret_cast<shared_ptr<XdmfArray> *>(resultPointer);
shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
return returnArray;
}
private:
PythonFunction(PyObject * functionref)
{
if (PyCallable_Check(functionref) == 1) {
mInternalFunction = functionref;
}
else {
XdmfError::message(XdmfError::FATAL,
"Error: Function is not callable");
}
}
PyObject * mInternalFunction;
};
class PythonOperation : public XdmfFunction::XdmfOperationInternal {
public:
static shared_ptr<PythonOperation>
New(PyObject * operationref)
{
shared_ptr<PythonOperation> p (new PythonOperation(operationref));
return p;
}
~PythonOperation()
{
}
virtual shared_ptr<XdmfArray> execute(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
{
swig_type_info * paramType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
PyObject * pyVal1 = SWIG_NewPointerObj(static_cast<void*>(& val1), paramType, SWIG_POINTER_NEW);
PyObject * pyVal2 = SWIG_NewPointerObj(static_cast<void*>(& val2), paramType, SWIG_POINTER_NEW);
PyObject * args = PyTuple_New(2);
PyTuple_SetItem(args, 0, pyVal1);
PyTuple_SetItem(args, 1, pyVal2);
PyObject * resultObject = PyObject_CallObject(mInternalOperation, args);
void * resultPointer = 0;
swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
SWIG_ConvertPtr(resultObject, &resultPointer, returnType, 0);
shared_ptr<XdmfArray> * returnArrayPointer = reinterpret_cast<shared_ptr<XdmfArray> *>(resultPointer);
shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
return returnArray;
}
private:
PythonOperation(PyObject * operationref)
{
if (PyCallable_Check(operationref) == 1) {
mInternalOperation = operationref;
}
else {
XdmfError::message(XdmfError::FATAL,
"Error: Operation is not callable");
}
}
PyObject * mInternalOperation;
};
%}
static int addFunction(std::string newName, PyObject * functionref)
{
shared_ptr<PythonFunction> newFunction = PythonFunction::New(functionref);
return XdmfFunction::addFunction(newName, newFunction);
}
static int addOperation(char newName, PyObject * calcref, int priority)
{
shared_ptr<PythonOperation> newOperation = PythonOperation::New(calcref);
return XdmfFunction::addOperation(newName, newOperation, priority);
}
};
#endif /* SWIGPYTHON */
%include boost_shared_ptr.i
......@@ -365,6 +477,7 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%shared_ptr(XdmfArrayType)
%shared_ptr(XdmfCoreItemFactory)
%shared_ptr(XdmfCoreReader)
%shared_ptr(XdmfFunction)
%shared_ptr(XdmfHDF5Controller)
%shared_ptr(XdmfHDF5Writer)
#ifdef XDMF_BUILD_DSM
......@@ -394,6 +507,7 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%include XdmfSparseMatrix.hpp
%include XdmfSystemUtils.hpp
%include XdmfVisitor.hpp
%include XdmfFunction.hpp
%include XdmfHeavyDataController.hpp
%include XdmfHeavyDataWriter.hpp
......
......@@ -23,6 +23,7 @@
#include "XdmfArray.hpp"
#include "XdmfCoreItemFactory.hpp"
#include "XdmfError.hpp"
XdmfCoreItemFactory::XdmfCoreItemFactory()
{
......@@ -34,11 +35,88 @@ XdmfCoreItemFactory::~XdmfCoreItemFactory()
shared_ptr<XdmfItem>
XdmfCoreItemFactory::createItem(const std::string & itemTag,
const std::map<std::string, std::string> &,
const std::vector<shared_ptr<XdmfItem> > &) const
const std::map<std::string, std::string> & itemProperties,
const std::vector<shared_ptr<XdmfItem> > & childItems) const
{
if(itemTag.compare(XdmfArray::ItemTag) == 0) {
return XdmfArray::New();
}
else if (itemTag.compare(XdmfFunction::ItemTag) == 0) {
std::map<std::string, std::string>::const_iterator type =
itemProperties.find("ConstructedType");
std::string arraySubType;
if(type == itemProperties.end()) {
// If no type is specified an array is generated
arraySubType = XdmfArray::ItemTag;
}
else {
arraySubType = type->second;
}
std::map<std::string, std::string>::const_iterator expression =
itemProperties.find("Expression");
std::string expressionToParse;
if(expression == itemProperties.end()) {
try {
XdmfError::message(XdmfError::FATAL,
"Error: Function found no expression");
}
catch (XdmfError e) {
throw e;
}
}
else {
expressionToParse = expression->second;
}
std::map<std::string, shared_ptr<XdmfArray> > variableCollection;
for (unsigned int i = 0; i < childItems.size(); ++i) {
try {
shared_ptr<XdmfArray> tempArray =
shared_dynamic_cast<XdmfArray>(childItems[i]);
variableCollection[tempArray->getName()] = tempArray;
tempArray->read();
}
catch (...) {
try {
XdmfError::message(XdmfError::FATAL,
"Error: Function passed non-Array item");
}
catch (XdmfError e) {
throw e;
}
}
}
shared_ptr<XdmfArray> parsedArray = shared_ptr<XdmfArray>();
try {
parsedArray = XdmfFunction::evaluateExpression(expressionToParse,
variableCollection);
}
catch (XdmfError e) {
throw e;
}
if (arraySubType != XdmfArray::ItemTag) {
// The properties and children aren't really needed
// to generate the object, but the factory still requires them.
std::vector<shared_ptr<XdmfItem> > newArrayChildren;
shared_ptr<XdmfArray> returnArray = XdmfArray::New();
// This should generate an item that corresponds to the tag provided
// the casting ensures that it is a subtype of array
// Using a factory to be able to build things outside of core
returnArray = shared_dynamic_cast<XdmfArray>(createItem(
arraySubType,
itemProperties,
newArrayChildren));
returnArray->insert(0, parsedArray, 0, parsedArray->getSize());
returnArray->setFunction(XdmfFunction::New(expressionToParse,
variableCollection));
return returnArray;
}
else {
parsedArray->setFunction(XdmfFunction::New(expressionToParse,
variableCollection));
return parsedArray;
}
}
return shared_ptr<XdmfItem>();
}
......@@ -245,7 +245,6 @@ public:
}
}
xmlAttrPtr currAttribute = currNode->properties;
while(currAttribute != NULL) {
itemProperties.insert(std::make_pair((char *)currAttribute->name,
......
......@@ -44,18 +44,34 @@ XdmfError::getLevelLimit()
return XdmfError::mLevelLimit;
}
XdmfError::Level
XdmfError::getSuppressionLevel()
{
return XdmfError::mSuppressLevel;
}
void
XdmfError::setLevelLimit(Level l)
{
XdmfError::mLevelLimit = l;
}
void
XdmfError::setSuppressionLevel(Level l)
{
XdmfError::mSuppressLevel = l;
}
void
XdmfError::message(Level level, std::string msg)
{
if(level<=XdmfError::getLevelLimit())
if (level>=XdmfError::getSuppressionLevel())
{
XdmfError::WriteToStream(msg);
}
if(level<=XdmfError::getLevelLimit()) {
throw XdmfError(level, msg);
}
}
void
......@@ -83,4 +99,5 @@ XdmfError::WriteToStream(std::string msg)
******************************************/
XdmfError::Level XdmfError::mLevelLimit = XdmfError::FATAL;
XdmfError::Level XdmfError::mSuppressLevel = XdmfError::DEBUG;
std::streambuf* XdmfError::mBuf=std::cout.rdbuf();
......@@ -105,6 +105,27 @@ public:
*/
static void setLevelLimit(Level l);
/**
* Sets the minimum Error level that displays messages with the message function.
*
* Example of use:
*
* C++
*
* @dontinclude ExampleXdmfError.cpp
* @skipline //#setSuppressionLevel
* @until //#setSuppressionLevel
*
* Python
*
* @dontinclude XdmfExampleError.py
* @skipline #//setSuppressionLevel
* @until #//setSuppressionLevel
*
* @param l The new minimum error level to display a message
*/
static void setSuppressionLevel(Level l);
/**
* Gets the level limit for Errors.
*
......@@ -128,6 +149,23 @@ public:
*/
static Level getLevelLimit();
/**
* Gets the minimum Error level that displays messages with the message function.
*
* @dontinclude ExampleXdmfError.cpp
* @skipline //#getSuppressionLevel
* @until //#getSuppressionLevel
*
* Python
*
* @dontinclude XdmfExampleError.py
* @skipline #//getSuppressionLevel
* @until #//getSuppressionLevel
*
* @return The minimum error level to display a message
*/
static Level getSuppressionLevel();
/**
* Alternate constructor for XdmfError exceptions.
* This one automatically prints out the message provided if the error level is within range.
......@@ -199,6 +237,7 @@ public:
private: