XdmfTopology.cpp 5.86 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfTopology.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.                                                 */
/*                                                                           */
/*****************************************************************************/
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
23

24
#include <sstream>
25
#include <utility>
26
#include "XdmfError.hpp"
27
#include "XdmfFunction.hpp"
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
28
#include "XdmfTopology.hpp"
29
#include "XdmfTopologyType.hpp"
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
30

31
shared_ptr<XdmfTopology>
32
XdmfTopology::New()
33
{
34
  shared_ptr<XdmfTopology> p(new XdmfTopology());
35
  return p;
36 37
}

38
XdmfTopology::XdmfTopology() :
39
  mType(XdmfTopologyType::NoTopologyType())
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
40 41 42 43 44 45 46
{
}

XdmfTopology::~XdmfTopology()
{
}

47
const std::string XdmfTopology::ItemTag = "Topology";
48

49 50
std::string
XdmfTopology::getItemTag() const
51
{
52
  return ItemTag;
53 54
}

55 56
std::map<std::string, std::string>
XdmfTopology::getItemProperties() const
57
{
58 59
  std::map<std::string, std::string> topologyProperties;
  mType->getProperties(topologyProperties);
60
  if(mType->getCellType() != XdmfTopologyType::Structured) {
61 62
    std::stringstream numElements;
    numElements << this->getNumberElements();
63
    topologyProperties.insert(std::make_pair("Dimensions", numElements.str()));
64 65
  }
  return topologyProperties;
66 67
}

68 69
unsigned int
XdmfTopology::getNumberElements() const
70
{
71
  // deal with special cases first (mixed / no topology)
72
  if(mType->getNodesPerElement() == 0) {
73 74 75 76 77 78 79
    if(mType == XdmfTopologyType::Mixed()) {
      unsigned int index = 0;
      unsigned int numberElements = 0;
      // iterate over all values in connectivity, pulling topology type ids
      // and counting number of elements
      while(index < this->getSize()) {
        const unsigned int id = this->getValue<unsigned int>(index);
80
        const shared_ptr<const XdmfTopologyType> topologyType =
81 82
          XdmfTopologyType::New(id);
        if(topologyType == NULL) {
83 84 85
          XdmfError::message(XdmfError::FATAL,
                             "Invalid topology type id found in connectivity "
                             "when parsing mixed topology.");
86 87
        }
        if(topologyType == XdmfTopologyType::Polyvertex()) {
88
          const unsigned int numberPolyvertexElements =
89 90 91 92
            this->getValue<unsigned int>(index + 1);
          numberElements += numberPolyvertexElements;
          index += numberPolyvertexElements + 2;
        }
93
        else if(topologyType == XdmfTopologyType::Polyline(0) ||
94
                topologyType == XdmfTopologyType::Polygon(0)) {
95
          const unsigned int numberNodes =
96 97 98 99 100 101 102 103 104 105 106 107
            this->getValue<unsigned int>(index + 1);
          numberElements += 1;
          index += numberNodes + 2;
        }
        else {
          // add 1 to element count and move to next element id
          numberElements += 1;
          index += topologyType->getNodesPerElement() + 1;
        }
      }
      return numberElements;
    }
108 109 110
    return 0;
  }
  return this->getSize() / mType->getNodesPerElement();
111 112
}

113
shared_ptr<const XdmfTopologyType>
114
XdmfTopology::getType() const
115
{
116
  return mType;
117 118
}

119 120
void
XdmfTopology::populateItem(const std::map<std::string, std::string> & itemProperties,
121
                           const std::vector<shared_ptr<XdmfItem> > & childItems,
122
                           const XdmfCoreReader * const reader)
123
{
124 125
  XdmfItem::populateItem(itemProperties, childItems, reader);
  mType = XdmfTopologyType::New(itemProperties);
126
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter = childItems.begin();
127 128
      iter != childItems.end();
      ++iter) {
129
    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
130
      this->swap(array);
131 132 133 134 135
      if (array->getReference()) {
        this->setReference(array->getReference());
        this->setReadMode(XdmfArray::Reference);
      }
      break;
136 137
    }
  }
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153

  std::map<std::string, std::string>::const_iterator type =
    itemProperties.find("Offset");
  if (type != itemProperties.end()) {
    // Convert to double
    double offset = atof(type->second.c_str());
    std::stringstream expressionStream;
    expressionStream << offset << "+X";
    std::map<std::string, shared_ptr<XdmfArray> > offsetMap;
    shared_ptr<XdmfArray> offsetBase = XdmfArray::New();
    this->swap(offsetBase);
    offsetMap["X"] = offsetBase;
    shared_ptr<XdmfFunction> offsetFunction = XdmfFunction::New(expressionStream.str(), offsetMap);
    this->setReference(offsetFunction);
    this->setReadMode(XdmfArray::Reference);
  }
154 155
}

156
void
157
XdmfTopology::setType(const shared_ptr<const XdmfTopologyType> type)
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
158
{
159
  mType = type;
Ken Leiter (Civ's avatar
Ken Leiter (Civ committed
160
}