XdmfCurvilinearGrid.cpp 8.46 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 : XdmfCurviliniearGrid.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.                                                 */
/*                                                                           */
/*****************************************************************************/
23 24 25

#include <cmath>
#include "XdmfArray.hpp"
26
#include "XdmfCurvilinearGrid.hpp"
27
#include "XdmfGeometry.hpp"
28 29
#include "XdmfTopology.hpp"
#include "XdmfTopologyType.hpp"
30
#include "XdmfError.hpp"
31 32 33 34

/**
 * PIMPL
 */
35
class XdmfCurvilinearGrid::XdmfCurvilinearGridImpl {
36 37 38

public:

39 40 41 42 43
  class XdmfTopologyCurvilinear : public XdmfTopology
  {

  public:

44
    static shared_ptr<XdmfTopologyCurvilinear>
45 46
    New(const XdmfCurvilinearGrid * const curvilinearGrid)
    {
47 48 49
      shared_ptr<XdmfTopologyCurvilinear> 
        p(new XdmfTopologyCurvilinear(curvilinearGrid));
      return p;
50 51 52 53 54
    }

    unsigned int
    getNumberElements() const
    {
55
      const shared_ptr<const XdmfArray> dimensions = 
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
        mCurvilinearGrid->getDimensions();
      if(dimensions->getSize() == 0) {
        return 0;
      }
      unsigned int toReturn = 1;
      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
        toReturn *= (dimensions->getValue<unsigned int>(i) - 1);
      }
      return toReturn;
    }

  private:

    XdmfTopologyCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
      mCurvilinearGrid(curvilinearGrid)
    {
72
      this->setType(XdmfTopologyTypeCurvilinear::New(curvilinearGrid));
73 74 75 76 77 78 79 80 81 82
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;
  };

  class XdmfTopologyTypeCurvilinear : public XdmfTopologyType
  {

  public:

83
    static shared_ptr<const XdmfTopologyTypeCurvilinear>
84 85
    New(const XdmfCurvilinearGrid * const curvilinearGrid)
    {
86
      shared_ptr<const XdmfTopologyTypeCurvilinear>
87 88 89 90
        p(new XdmfTopologyTypeCurvilinear(curvilinearGrid));
      return p;
    }

91 92 93 94 95 96 97 98 99 100 101 102
    unsigned int
    getEdgesPerElement() const
    {
      const unsigned int dimensions = 
        mCurvilinearGrid->getDimensions()->getSize();
      if(dimensions == 2) {
        return 4;
      }
      else if(dimensions == 3) {
        return 12;
      }
      else {
103 104 105
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeCurvilinear::getEdgesPerElement");
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
      }
      return 0;
    }

    unsigned int
    getFacesPerElement() const
    {
      const unsigned int dimensions = 
        mCurvilinearGrid->getDimensions()->getSize();
      if(dimensions == 2) {
        return 1;
      }
      else if(dimensions == 3) {
        return 6;
      }
      else {
122 123 124
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeCurvilinear::getFacesPerElement");
125 126 127 128
      }
      return 0;
    }

129 130 131 132 133 134 135 136 137 138 139 140
    unsigned int
    getNodesPerElement() const
    {
      // 2^Dimensions
      // e.g. 1D = 2 nodes per element and 2D = 4 nodes per element.
      return (unsigned int)
        std::pow(2, (double)mCurvilinearGrid->getDimensions()->getSize());
    }

    void
    getProperties(std::map<std::string, std::string> & collectedProperties) const
    {
141
      shared_ptr<const XdmfArray> dimensions =
142 143 144 145 146 147 148 149
        mCurvilinearGrid->getDimensions();
      if(dimensions->getSize() == 3) {
        collectedProperties["Type"] = "3DSMesh";
      }
      else if(dimensions->getSize() == 2) {
        collectedProperties["Type"] = "2DSMesh";
      }
      else {
150 151 152
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeCurvilinear::getProperties");
153 154 155 156 157 158 159
      }
      collectedProperties["Dimensions"] = dimensions->getValuesString();
    }

  private:

    XdmfTopologyTypeCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
160 161 162 163 164 165 166
      XdmfTopologyType(0,
                       0,
                       std::vector<shared_ptr<const XdmfTopologyType> >(),
                       0,
                       "foo",
                       XdmfTopologyType::Structured,
                       0x1110),
167 168 169 170 171 172 173 174
      mCurvilinearGrid(curvilinearGrid)
    {
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;

  };

175
  XdmfCurvilinearGridImpl(const shared_ptr<XdmfArray> numPoints) :
176 177 178 179
    mDimensions(numPoints)
  {
  }

180
  shared_ptr<XdmfArray> mDimensions;
181 182 183

};

184
shared_ptr<XdmfCurvilinearGrid>
185 186
XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
                         const unsigned int yNumPoints)
187
{
188
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
189 190 191
  numPoints->resize<unsigned int>(2);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
192
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
193
  return p;
194 195
}

196
shared_ptr<XdmfCurvilinearGrid>
197 198 199
XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
                         const unsigned int yNumPoints,
                         const unsigned int zNumPoints)
200
{
201
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
202 203 204 205
  numPoints->resize<unsigned int>(3);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
  numPoints->insert(2, zNumPoints);
206
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
207
  return p;
208 209
}

210 211
shared_ptr<XdmfCurvilinearGrid>
XdmfCurvilinearGrid::New(const shared_ptr<XdmfArray> numPoints)
212
{
213
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
214
  return p;
215 216
}

217
XdmfCurvilinearGrid::XdmfCurvilinearGrid(const shared_ptr<XdmfArray> numPoints) :
218 219 220
  XdmfGrid(XdmfGeometry::New(),
           XdmfCurvilinearGridImpl::XdmfTopologyCurvilinear::New(this)),
  mImpl(new XdmfCurvilinearGridImpl(numPoints))
221 222 223
{
}

224
XdmfCurvilinearGrid::~XdmfCurvilinearGrid()
225
{
226
  delete mImpl;
227 228
}

229
const std::string XdmfCurvilinearGrid::ItemTag = "Grid";
230

231
shared_ptr<XdmfArray>
232
XdmfCurvilinearGrid::getDimensions()
233
{
234 235
  return boost::const_pointer_cast<XdmfArray>
    (static_cast<const XdmfCurvilinearGrid &>(*this).getDimensions());
236 237
}

238
shared_ptr<const XdmfArray>
239
XdmfCurvilinearGrid::getDimensions() const
240
{
241
  return mImpl->mDimensions;
242 243
}

244
shared_ptr<XdmfGeometry>
245
XdmfCurvilinearGrid::getGeometry()
246
{
247 248
  return boost::const_pointer_cast<XdmfGeometry>
    (static_cast<const XdmfGrid &>(*this).getGeometry());
249 250
}

251 252
void
XdmfCurvilinearGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
253
                                  const std::vector<shared_ptr<XdmfItem> > & childItems,
254
                                  const XdmfCoreReader * const reader)
255
{
256 257
  XdmfGrid::populateItem(itemProperties, childItems, reader);

258
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
259 260 261
        childItems.begin();
      iter != childItems.end();
      ++iter) {
262 263
    if(shared_ptr<XdmfCurvilinearGrid> curvilinearGrid =
       shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
264 265 266
      mImpl->mDimensions = curvilinearGrid->getDimensions();
    }
  }
267 268
}

269
void
270
XdmfCurvilinearGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
271
{
272
  mImpl->mDimensions = dimensions;
273 274
}

275
void
276
XdmfCurvilinearGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
277
{
278
  mGeometry = geometry;
279 280
}