/*****************************************************************************/ /* XDMF */ /* eXtensible Data Model and Format */ /* */ /* Id : XdmfRectilinearGrid.cpp */ /* */ /* Author: */ /* Kenneth Leiter */ /* kenneth.leiter@arl.army.mil */ /* US Army Research Laboratory */ /* Aberdeen Proving Ground, MD */ /* */ /* Copyright @ 2011 US Army Research Laboratory */ /* All Rights Reserved */ /* See Copyright.txt for details */ /* */ /* This software is distributed WITHOUT ANY WARRANTY; without */ /* even the implied warranty of MERCHANTABILITY or FITNESS */ /* FOR A PARTICULAR PURPOSE. See the above copyright notice */ /* for more information. */ /* */ /*****************************************************************************/ #include #include "XdmfArray.hpp" #include "XdmfGeometry.hpp" #include "XdmfGeometryType.hpp" #include "XdmfRectilinearGrid.hpp" #include "XdmfTopology.hpp" #include "XdmfTopologyType.hpp" #include "XdmfError.hpp" /** * PIMPL */ class XdmfRectilinearGrid::XdmfRectilinearGridImpl : public XdmfGridImpl { public: class XdmfGeometryRectilinear : public XdmfGeometry { public: static shared_ptr New(XdmfRectilinearGrid * const rectilinearGrid) { shared_ptr p(new XdmfGeometryRectilinear(rectilinearGrid)); return p; } unsigned int getNumberPoints() const { const shared_ptr dimensions = mRectilinearGrid->getDimensions(); if(dimensions->getSize() == 0) { return 0; } unsigned int toReturn = 1; for(unsigned int i=0; igetSize(); ++i) { toReturn *= dimensions->getValue(i); } return toReturn; } bool isInitialized() const { return true; } void traverse(const shared_ptr visitor) { const std::vector > & coordinates = mRectilinearGrid->getCoordinates(); for (unsigned int i = 0; i < coordinates.size(); ++i) { coordinates[i]->accept(visitor); } } private: XdmfGeometryRectilinear(XdmfRectilinearGrid * const rectilinearGrid) : mRectilinearGrid(rectilinearGrid) { this->setType(XdmfGeometryTypeRectilinear::New(mRectilinearGrid)); } const XdmfRectilinearGrid * const mRectilinearGrid; }; class XdmfGeometryTypeRectilinear : public XdmfGeometryType { public: static shared_ptr New(const XdmfRectilinearGrid * const rectilinearGrid) { shared_ptr p(new XdmfGeometryTypeRectilinear(rectilinearGrid)); return p; } unsigned int getDimensions() const { return mRectilinearGrid->getDimensions()->getSize(); } void getProperties(std::map & collectedProperties) const { const unsigned int dimensions = this->getDimensions(); if(dimensions == 3) { collectedProperties["Type"] = "VXVYVZ"; } else if(dimensions == 2) { collectedProperties["Type"] = "VXVY"; } else { collectedProperties["Type"] = "VECTORED"; } } private: XdmfGeometryTypeRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) : XdmfGeometryType("", 0), mRectilinearGrid(rectilinearGrid) { } const XdmfRectilinearGrid * const mRectilinearGrid; }; class XdmfTopologyRectilinear : public XdmfTopology { public: static shared_ptr New(const XdmfRectilinearGrid * const rectilinearGrid) { shared_ptr p(new XdmfTopologyRectilinear(rectilinearGrid)); return p; } bool isInitialized() const { return true; } unsigned int getNumberElements() const { const shared_ptr dimensions = mRectilinearGrid->getDimensions(); if(dimensions->getSize() == 0) { return 0; } unsigned int toReturn = 1; for(unsigned int i=0; igetSize(); ++i) { toReturn *= (dimensions->getValue(i) - 1); } return toReturn; } private: XdmfTopologyRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) : mRectilinearGrid(rectilinearGrid) { this->setType(XdmfTopologyTypeRectilinear::New(rectilinearGrid)); } const XdmfRectilinearGrid * const mRectilinearGrid; }; class XdmfTopologyTypeRectilinear : public XdmfTopologyType { public: static shared_ptr New(const XdmfRectilinearGrid * const rectilinearGrid) { shared_ptr p(new XdmfTopologyTypeRectilinear(rectilinearGrid)); return p; } unsigned int getEdgesPerElement() const { return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 1); } unsigned int getFacesPerElement() const { return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 2); } unsigned int getNodesPerElement() const { return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 0); } void getProperties(std::map & collectedProperties) const { shared_ptr dimensions = mRectilinearGrid->getDimensions(); if(dimensions->getSize() == 3) { collectedProperties["Type"] = "3DRectMesh"; } else if(dimensions->getSize() == 2) { collectedProperties["Type"] = "2DRectMesh"; } else { collectedProperties["Type"] = "RectMesh"; } collectedProperties["Dimensions"] = dimensions->getValuesString(); } private: XdmfTopologyTypeRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) : XdmfTopologyType(0, 0, std::vector >(), 0, "foo", XdmfTopologyType::Structured, 0x1101), mRectilinearGrid(rectilinearGrid) { } const XdmfRectilinearGrid * const mRectilinearGrid; }; XdmfRectilinearGridImpl(const std::vector > & coordinates) : mCoordinates(coordinates.begin(), coordinates.end()) { mGridType = "Rectilinear"; } XdmfGridImpl * duplicate() { return new XdmfRectilinearGridImpl(mCoordinates); } std::vector > mCoordinates; }; shared_ptr XdmfRectilinearGrid::New(const shared_ptr xCoordinates, const shared_ptr yCoordinates) { std::vector > axesCoordinates; axesCoordinates.resize(2); axesCoordinates[0] = xCoordinates; axesCoordinates[1] = yCoordinates; shared_ptr p(new XdmfRectilinearGrid(axesCoordinates)); return p; } shared_ptr XdmfRectilinearGrid::New(const shared_ptr xCoordinates, const shared_ptr yCoordinates, const shared_ptr zCoordinates) { std::vector > axesCoordinates; axesCoordinates.resize(3); axesCoordinates[0] = xCoordinates; axesCoordinates[1] = yCoordinates; axesCoordinates[2] = zCoordinates; shared_ptr p(new XdmfRectilinearGrid(axesCoordinates)); return p; } shared_ptr XdmfRectilinearGrid::New(const std::vector > & axesCoordinates) { shared_ptr p(new XdmfRectilinearGrid(axesCoordinates)); return p; } XdmfRectilinearGrid::XdmfRectilinearGrid(const std::vector > & axesCoordinates) : XdmfGrid(XdmfRectilinearGridImpl::XdmfGeometryRectilinear::New(this), XdmfRectilinearGridImpl::XdmfTopologyRectilinear::New(this)) { mImpl = new XdmfRectilinearGridImpl(axesCoordinates); } XdmfRectilinearGrid::XdmfRectilinearGrid(XdmfRectilinearGrid & refGrid): XdmfGrid(refGrid) { mTopology = XdmfRectilinearGridImpl::XdmfTopologyRectilinear::New(this); mGeometry = XdmfRectilinearGridImpl::XdmfGeometryRectilinear::New(this); } XdmfRectilinearGrid::~XdmfRectilinearGrid() { if (mImpl) { delete mImpl; } mImpl = NULL; } const std::string XdmfRectilinearGrid::ItemTag = "Grid"; void XdmfRectilinearGrid::copyGrid(shared_ptr sourceGrid) { XdmfGrid::copyGrid(sourceGrid); if (shared_ptr classedGrid = shared_dynamic_cast(sourceGrid)) { // Copy stucture from read grid to this grid this->setCoordinates(classedGrid->getCoordinates()); } } shared_ptr XdmfRectilinearGrid::getCoordinates(const unsigned int axisIndex) { return boost::const_pointer_cast (static_cast (*this).getCoordinates(axisIndex)); } shared_ptr XdmfRectilinearGrid::getCoordinates(const unsigned int axisIndex) const { if(axisIndex < ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size()) { return ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates[axisIndex]; } return shared_ptr(); } std::vector > XdmfRectilinearGrid::getCoordinates() { return static_cast(*this).getCoordinates(); } const std::vector > XdmfRectilinearGrid::getCoordinates() const { return ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates; } shared_ptr XdmfRectilinearGrid::getDimensions() { return boost::const_pointer_cast (static_cast(*this).getDimensions()); } shared_ptr XdmfRectilinearGrid::getDimensions() const { shared_ptr dimensions = XdmfArray::New(); std::vector > heldCoordinates = ((XdmfRectilinearGridImpl*)mImpl)->mCoordinates; dimensions->reserve(heldCoordinates.size()); for (unsigned int i = 0; i < heldCoordinates.size(); ++i) { dimensions->pushBack(heldCoordinates[i]->getSize()); } return dimensions; } void XdmfRectilinearGrid::populateItem(const std::map & itemProperties, const std::vector > & childItems, const XdmfCoreReader * const reader) { XdmfGrid::populateItem(itemProperties, childItems, reader); for(std::vector >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter) { if(shared_ptr rectilinearGrid = shared_dynamic_cast(*iter)) { if(rectilinearGrid->getGeometry()->getType()->getDimensions() > 0) { this->setCoordinates(rectilinearGrid->getCoordinates()); break; } } } } void XdmfRectilinearGrid::read() { if (mGridController) { if (shared_ptr grid = shared_dynamic_cast(mGridController->read())) { // Copy stucture from read grid to this grid copyGrid(grid); } else if (shared_dynamic_cast(mGridController->read())) { XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch"); } else { XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference"); } } } void XdmfRectilinearGrid::release() { XdmfGrid::release(); ((XdmfRectilinearGridImpl*)mImpl)->mCoordinates.clear(); } void XdmfRectilinearGrid::setCoordinates(const unsigned int axisIndex, const shared_ptr axisCoordinates) { if(((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size() <= axisIndex) { ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.reserve(axisIndex + 1); unsigned int numArraysToInsert = axisIndex - ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size() + 1; for(unsigned int i=0; imCoordinates.push_back(XdmfArray::New()); } } ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates[axisIndex] = axisCoordinates; this->setIsChanged(true); } void XdmfRectilinearGrid::setCoordinates(const std::vector > axesCoordinates) { ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates = axesCoordinates; this->setIsChanged(true); } // C Wrappers XDMFRECTILINEARGRID * XdmfRectilinearGridNew(XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl) { try { std::vector > holderVector; for (unsigned int i = 0; i < numCoordinates; ++i) { if (passControl) { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i])); } else { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i], XdmfNullDeleter())); } } shared_ptr generatedGrid = XdmfRectilinearGrid::New(holderVector); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } catch (...) { std::vector > holderVector; for (unsigned int i = 0; i < numCoordinates; ++i) { if (passControl) { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i])); } else { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i], XdmfNullDeleter())); } } shared_ptr generatedGrid = XdmfRectilinearGrid::New(holderVector); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } } XDMFRECTILINEARGRID * XdmfRectilinearGridNew2D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, int passControl) { try { if (passControl) { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates), shared_ptr((XdmfArray *)yCoordinates)); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } else { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)yCoordinates, XdmfNullDeleter())); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } } catch (...) { if (passControl) { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates), shared_ptr((XdmfArray *)yCoordinates)); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } else { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)yCoordinates, XdmfNullDeleter())); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } } } XDMFRECTILINEARGRID * XdmfRectilinearGridNew3D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, XDMFARRAY * zCoordinates, int passControl) { try { if (passControl) { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates), shared_ptr((XdmfArray *)yCoordinates), shared_ptr((XdmfArray *)zCoordinates)); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } else { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)yCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)zCoordinates, XdmfNullDeleter())); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } } catch (...) { if (passControl) { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates), shared_ptr((XdmfArray *)yCoordinates), shared_ptr((XdmfArray *)zCoordinates)); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } else { shared_ptr generatedGrid = XdmfRectilinearGrid::New(shared_ptr((XdmfArray *)xCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)yCoordinates, XdmfNullDeleter()), shared_ptr((XdmfArray *)zCoordinates, XdmfNullDeleter())); return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get())))); } } } XDMFARRAY * XdmfRectilinearGridGetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int axisIndex, int * status) { XDMF_ERROR_WRAP_START(status) XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); return (XDMFARRAY *)((void *)(gridPointer->getCoordinates(axisIndex).get())); XDMF_ERROR_WRAP_END(status) return NULL; } XDMFARRAY ** XdmfRectilinearGridGetCoordinates(XDMFRECTILINEARGRID * grid, int * status) { XDMF_ERROR_WRAP_START(status) try { XDMFARRAY ** returnPointer; XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); std::vector > heldCoordinates = gridPointer->getCoordinates(); returnPointer = new XDMFARRAY *[heldCoordinates.size()](); for (unsigned int i = 0; i < heldCoordinates.size(); ++i) { XDMFARRAY * insertArray = (XDMFARRAY *)((void *)(new XdmfArray(*(heldCoordinates[i].get())))); returnPointer[i] = insertArray; } return returnPointer; } catch (...) { XDMFARRAY ** returnPointer; XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); std::vector > heldCoordinates = gridPointer->getCoordinates(); returnPointer = new XDMFARRAY *[heldCoordinates.size()](); for (unsigned int i = 0; i < heldCoordinates.size(); ++i) { XDMFARRAY * insertArray = (XDMFARRAY *)((void *)(new XdmfArray(*(heldCoordinates[i].get())))); returnPointer[i] = insertArray; } return returnPointer; } XDMF_ERROR_WRAP_END(status) return NULL; } int XdmfRectilinearGridGetNumberCoordinates(XDMFRECTILINEARGRID * grid, int * status) { XDMF_ERROR_WRAP_START(status) XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); std::vector > heldCoordinates = gridPointer->getCoordinates(); return heldCoordinates.size(); XDMF_ERROR_WRAP_END(status) return 0; } XDMFARRAY * XdmfRectilinearGridGetDimensions(XDMFRECTILINEARGRID * grid, int * status) { XDMF_ERROR_WRAP_START(status) try { XdmfArray * copyArray; shared_ptr returnDimensions; XdmfItem * classedPointer = (XdmfItem *)grid; XdmfGrid * classedGrid = dynamic_cast(classedPointer); XdmfRectilinearGrid * gridPointer = dynamic_cast(classedGrid); XDMFARRAY * returnArray; returnDimensions = gridPointer->getDimensions(); copyArray = new XdmfArray(*(returnDimensions.get())); void * copyVoid = (void *)copyArray; returnArray = (XDMFARRAY *) copyVoid; returnDimensions.reset(); return returnArray; } catch (...) { XdmfArray * copyArray; shared_ptr returnDimensions; XdmfItem * classedPointer = (XdmfItem *)grid; XdmfGrid * classedGrid = dynamic_cast(classedPointer); XdmfRectilinearGrid * gridPointer = dynamic_cast(classedGrid); XDMFARRAY * returnArray; returnDimensions = gridPointer->getDimensions(); copyArray = new XdmfArray(*(returnDimensions.get())); void * copyVoid = (void *)copyArray; returnArray = (XDMFARRAY *) copyVoid; returnDimensions.reset(); return returnArray; } XDMF_ERROR_WRAP_END(status) return NULL; } void XdmfRectilinearGridSetCoordinates(XDMFRECTILINEARGRID * grid, XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl, int * status) { XDMF_ERROR_WRAP_START(status) XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); std::vector > holderVector; for (unsigned int i = 0; i < numCoordinates; ++i) { if (passControl) { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i])); } else { holderVector.push_back(shared_ptr((XdmfArray *)axesCoordinates[i], XdmfNullDeleter())); } } gridPointer->setCoordinates(holderVector); XDMF_ERROR_WRAP_END(status) } void XdmfRectilinearGridSetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int index, XDMFARRAY * coordinates, int passControl, int * status) { XDMF_ERROR_WRAP_START(status) XdmfItem * classedPointer = (XdmfItem *)grid; XdmfRectilinearGrid * gridPointer = dynamic_cast(classedPointer); if (passControl) { gridPointer->setCoordinates(index, shared_ptr((XdmfArray *)coordinates)); } else { gridPointer->setCoordinates(index, shared_ptr((XdmfArray *)coordinates, XdmfNullDeleter())); } XDMF_ERROR_WRAP_END(status) } XDMF_ITEM_C_CHILD_WRAPPER(XdmfRectilinearGrid, XDMFRECTILINEARGRID) XDMF_GRID_C_CHILD_WRAPPER(XdmfRectilinearGrid, XDMFRECTILINEARGRID)