/*****************************************************************************/ /* XDMF */ /* eXtensible Data Model and Format */ /* */ /* Id : XdmfUnstructuredGrid.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 "XdmfError.hpp" #include "XdmfGeometry.hpp" #include "XdmfGeometryType.hpp" #include "XdmfRegularGrid.hpp" #include "XdmfTopology.hpp" #include "XdmfTopologyType.hpp" #include "XdmfUnstructuredGrid.hpp" /** * local functions */ namespace { void convertRegularGeometry(unsigned int index, shared_ptr point, shared_ptr dimensions, shared_ptr brickSize, shared_ptr mGeometry) { const unsigned int nDim = dimensions->getValue(index); const double nBrickSize = brickSize->getValue(index); const double originalPoint = point->getValue(index); for(unsigned int i=0; iinsert(mGeometry->getSize(), point, 0, point->getSize()); } else { convertRegularGeometry(index - 1, point, dimensions, brickSize, mGeometry); } const double currPoint = point->getValue(index); point->insert(index, currPoint + nBrickSize); } point->insert(index, originalPoint); } void convertRegularTopology(shared_ptr dimensions, shared_ptr mTopology) { if(dimensions->getSize() == 2) { const unsigned int nx = dimensions->getValue(0); const unsigned int ny = dimensions->getValue(1); unsigned int offset = 0; for(unsigned int i=1; ipushBack(offset); mTopology->pushBack(offset + 1); mTopology->pushBack(offset + nx + 1); mTopology->pushBack(offset + nx); ++offset; } ++offset; } } else if(dimensions->getSize() == 3) { const unsigned int nx = dimensions->getValue(0); const unsigned int ny = dimensions->getValue(1); const unsigned int nz = dimensions->getValue(2); const unsigned int zOffset = nx * ny; unsigned int offset = 0; for(unsigned int i=1; ipushBack(offset); mTopology->pushBack(offset + 1); mTopology->pushBack(offset + nx + 1); mTopology->pushBack(offset + nx); mTopology->pushBack(offset + zOffset); mTopology->pushBack(offset + zOffset + 1); mTopology->pushBack(offset + zOffset + nx + 1); mTopology->pushBack(offset + zOffset + nx); ++offset; } ++offset; } offset += nx; } } } } class XdmfUnstructuredGrid::XdmfUnstructuredGridImpl : public XdmfGridImpl { public: XdmfUnstructuredGridImpl() { mGridType = "Unstructured"; } ~XdmfUnstructuredGridImpl() { } XdmfGridImpl * duplicate() { return new XdmfUnstructuredGridImpl(); } std::string getGridType() const { return mGridType; } }; shared_ptr XdmfUnstructuredGrid::New() { shared_ptr p(new XdmfUnstructuredGrid()); return p; } shared_ptr XdmfUnstructuredGrid::New(const shared_ptr regularGrid) { shared_ptr p(new XdmfUnstructuredGrid(regularGrid)); return p; } XdmfUnstructuredGrid::XdmfUnstructuredGrid() : XdmfGrid(XdmfGeometry::New(), XdmfTopology::New()) { mImpl = new XdmfUnstructuredGridImpl(); } XdmfUnstructuredGrid::XdmfUnstructuredGrid(const shared_ptr regularGrid) : XdmfGrid(XdmfGeometry::New(), XdmfTopology::New()) { mImpl = new XdmfUnstructuredGridImpl(); const shared_ptr origin = regularGrid->getOrigin(); shared_ptr brickSize = regularGrid->getBrickSize(); shared_ptr dimensions = regularGrid->getDimensions(); if(dimensions->getSize() != brickSize->getSize() || dimensions->getSize() != origin->getSize()) { XdmfError::message(XdmfError::FATAL, "Inconsistent brick, dimension, and origin sizes when" "converting regular grid to unstructured grid in " "XdmfUnstructuredGrid constructor"); } bool releaseOrigin = false; bool releaseBrickSize = false; bool releaseDimensions = false; if(!origin->isInitialized()) { origin->read(); releaseOrigin = true; } if(!brickSize->isInitialized()) { brickSize->read(); releaseBrickSize = true; } if(!dimensions->isInitialized()) { dimensions->read(); releaseDimensions = true; } shared_ptr geometryType; shared_ptr topologyType; if(origin->getSize() == 2) { geometryType = XdmfGeometryType::XY(); topologyType = XdmfTopologyType::Quadrilateral(); } else if(origin->getSize() == 3) { geometryType = XdmfGeometryType::XYZ(); topologyType = XdmfTopologyType::Hexahedron(); } else { XdmfError::message(XdmfError::FATAL, "Cannot convert regular grid of dimensions not 2 or 3 " "to XdmfUnstructuredGrid in XdmfUnstructuredGrid " "constructor"); } mGeometry->setType(geometryType); mTopology->setType(topologyType); shared_ptr point = XdmfArray::New(); point->insert(0, origin, 0, origin->getSize()); convertRegularGeometry(dimensions->getSize() - 1, point, dimensions, brickSize, mGeometry); convertRegularTopology(dimensions, mTopology); if(releaseOrigin) { origin->release(); } if(releaseBrickSize) { brickSize->release(); } if(releaseDimensions) { dimensions->release(); } } XdmfUnstructuredGrid::XdmfUnstructuredGrid(XdmfUnstructuredGrid & refGrid) : XdmfGrid(refGrid) { } XdmfUnstructuredGrid::~XdmfUnstructuredGrid() { if (mImpl) { delete mImpl; } mImpl = NULL; } const std::string XdmfUnstructuredGrid::ItemTag = "Grid"; void XdmfUnstructuredGrid::copyGrid(shared_ptr sourceGrid) { XdmfGrid::copyGrid(sourceGrid); if (shared_ptr classedGrid = shared_dynamic_cast(sourceGrid)) { this->setGeometry(classedGrid->getGeometry()); this->setTopology(classedGrid->getTopology()); } } shared_ptr XdmfUnstructuredGrid::getGeometry() { return boost::const_pointer_cast (static_cast(*this).getGeometry()); } std::string XdmfUnstructuredGrid::getItemTag() const { return ItemTag; } shared_ptr XdmfUnstructuredGrid::getTopology() { return boost::const_pointer_cast (static_cast(*this).getTopology()); } void XdmfUnstructuredGrid::read() { if (mGridController) { if (shared_ptr grid = shared_dynamic_cast(mGridController->read())) { 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 XdmfUnstructuredGrid::release() { XdmfGrid::release(); this->setGeometry(shared_ptr()); this->setTopology(shared_ptr()); } void XdmfUnstructuredGrid::setGeometry(const shared_ptr geometry) { mGeometry = geometry; } void XdmfUnstructuredGrid::setTopology(const shared_ptr topology) { mTopology = topology; } // C Wrappers XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNew() { try { shared_ptr generatedGrid = XdmfUnstructuredGrid::New(); return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get())))); } catch (...) { shared_ptr generatedGrid = XdmfUnstructuredGrid::New(); return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get())))); } } XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid, int * status) { XDMF_ERROR_WRAP_START(status) try { // Here it works when classed directly to the grid type, // in other cases this may not work. XdmfItem * tempPointer = (XdmfItem *)regularGrid; XdmfRegularGrid * classedPointer = dynamic_cast(tempPointer); shared_ptr originGrid = shared_ptr(classedPointer, XdmfNullDeleter()); shared_ptr generatedGrid = XdmfUnstructuredGrid::New(originGrid); return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get())))); } catch (...) { // Here it works when classed directly to the grid type, // in other cases this may not work. XdmfItem * tempPointer = (XdmfItem *)regularGrid; XdmfRegularGrid * classedPointer = dynamic_cast(tempPointer); shared_ptr originGrid = shared_ptr(classedPointer, XdmfNullDeleter()); shared_ptr generatedGrid = XdmfUnstructuredGrid::New(originGrid); return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get())))); } XDMF_ERROR_WRAP_END(status) return NULL; } XDMFGEOMETRY * XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid) { XdmfItem * tempPointer = (XdmfItem *)grid; XdmfUnstructuredGrid * classedPointer = dynamic_cast(tempPointer); return (XDMFGEOMETRY *)((void *)(classedPointer->getGeometry().get())); } XDMFTOPOLOGY * XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid) { XdmfItem * tempPointer = (XdmfItem *)grid; XdmfUnstructuredGrid * classedPointer = dynamic_cast(tempPointer); return (XDMFTOPOLOGY *)((void *)(classedPointer->getTopology().get())); } void XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid, XDMFGEOMETRY * geometry, int passControl) { XdmfItem * tempPointer = (XdmfItem *)grid; XdmfUnstructuredGrid * classedPointer = dynamic_cast(tempPointer); if (passControl) { classedPointer->setGeometry(shared_ptr((XdmfGeometry *)geometry)); } else { classedPointer->setGeometry(shared_ptr((XdmfGeometry *)geometry, XdmfNullDeleter())); } } void XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid, XDMFTOPOLOGY * topology, int passControl) { XdmfItem * tempPointer = (XdmfItem *)grid; XdmfUnstructuredGrid * classedPointer = dynamic_cast(tempPointer); if (passControl) { classedPointer->setTopology(shared_ptr((XdmfTopology *)topology)); } else { classedPointer->setTopology(shared_ptr((XdmfTopology *)topology, XdmfNullDeleter())); } } XDMF_ITEM_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID) XDMF_GRID_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID)