XdmfRegularGrid.cpp 13 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 : XdmfRegularGrid.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 26 27

#include <cmath>
#include "XdmfArray.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfGeometryType.hpp"
28
#include "XdmfRegularGrid.hpp"
29 30
#include "XdmfTopology.hpp"
#include "XdmfTopologyType.hpp"
31
#include "XdmfError.hpp"
32 33 34 35

/**
 * PIMPL
 */
36
class XdmfRegularGrid::XdmfRegularGridImpl {
37 38 39

public:

40 41 42 43 44
  class XdmfGeometryRegular : public XdmfGeometry
  {

  public:

45
    static shared_ptr<XdmfGeometryRegular>
46 47
    New(XdmfRegularGrid * const regularGrid)
    {
48
      shared_ptr<XdmfGeometryRegular> p(new XdmfGeometryRegular(regularGrid));
49 50 51 52 53 54
      return p;
    }

    unsigned int
    getNumberPoints() const
    {
55
      const shared_ptr<const XdmfArray> dimensions = 
56 57 58 59 60 61 62 63 64 65 66 67
        mRegularGrid->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);
      }
      return toReturn;
    }

    void
68
    traverse(const shared_ptr<XdmfBaseVisitor> visitor)
69
    {
70 71
      shared_ptr<XdmfArray> origin = mRegularGrid->getOrigin();
      shared_ptr<XdmfArray> brickSize = mRegularGrid->getBrickSize();
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
      origin->accept(visitor);
      brickSize->accept(visitor);
    }

  private:

    XdmfGeometryRegular(XdmfRegularGrid * const regularGrid) :
      mRegularGrid(regularGrid)
    {
      this->setType(XdmfGeometryTypeRegular::New(mRegularGrid));
    }

    XdmfRegularGrid * const mRegularGrid;
  };

  class XdmfGeometryTypeRegular : public XdmfGeometryType
  {

  public:

92
    static shared_ptr<const XdmfGeometryTypeRegular>
93 94
    New(const XdmfRegularGrid * const regularGrid)
    {
95
      shared_ptr<const XdmfGeometryTypeRegular> 
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
        p(new XdmfGeometryTypeRegular(regularGrid));
      return p;
    }

    unsigned int
    getDimensions() const
    {
      return mRegularGrid->getDimensions()->getSize();
    }

    void
    getProperties(std::map<std::string, std::string> & collectedProperties) const
    {
      const unsigned int dimensions = this->getDimensions();
      if(dimensions == 3) {
        collectedProperties["Type"] = "ORIGIN_DXDYDZ";
      }
      else if(dimensions == 2) {
        collectedProperties["Type"] = "ORIGIN_DXDY";
      }
      else {
117 118 119
        XdmfError::message(XdmfError::FATAL, 
                           "Dimensions not 2 or 3 in "
                           "XdmfGeometryTypeRegular::getProperties");
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
      }
    }

  private:

    XdmfGeometryTypeRegular(const XdmfRegularGrid * const regularGrid) :
      XdmfGeometryType("", 0),
      mRegularGrid(regularGrid)
    {
    }

    const XdmfRegularGrid * const mRegularGrid;

  };

  class XdmfTopologyRegular : public XdmfTopology
  {

  public:

140
    static shared_ptr<XdmfTopologyRegular>
141 142
    New(const XdmfRegularGrid * const regularGrid)
    {
143
      shared_ptr<XdmfTopologyRegular> p(new XdmfTopologyRegular(regularGrid));
144 145 146 147 148 149
      return p;
    }

    unsigned int
    getNumberElements() const
    {
150
      const shared_ptr<const XdmfArray> dimensions = 
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
        mRegularGrid->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:

    XdmfTopologyRegular(const XdmfRegularGrid * const regularGrid) :
      mRegularGrid(regularGrid)
    {
      this->setType(XdmfTopologyTypeRegular::New(regularGrid));
    }

    const XdmfRegularGrid * const mRegularGrid;
  };

  class XdmfTopologyTypeRegular : public XdmfTopologyType
  {

  public:

178
    static shared_ptr<const XdmfTopologyTypeRegular>
179 180
    New(const XdmfRegularGrid * const regularGrid)
    {
181
      shared_ptr<const XdmfTopologyTypeRegular>
182 183 184 185
        p(new XdmfTopologyTypeRegular(regularGrid));
      return p;
    }

186 187 188 189 190 191 192 193 194 195 196
    unsigned int
    getEdgesPerElement() const
    {
      const unsigned int dimensions = mRegularGrid->getDimensions()->getSize();
      if(dimensions == 2) {
        return 4;
      }
      else if(dimensions == 3) {
        return 12;
      }
      else {
197 198 199
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeRegular::getEdgesPerElement");
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
      }
      return 0;
    }

    unsigned int
    getFacesPerElement() const
    {
      const unsigned int dimensions = mRegularGrid->getDimensions()->getSize();
      if(dimensions == 2) {
        return 1;
      }
      else if(dimensions == 3) {
        return 6;
      }
      else {
215 216 217
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeRegular::getFacesPerElement");
218 219 220 221
      }
      return 0;
    }

222 223 224 225 226 227 228 229 230 231 232 233
    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)mRegularGrid->getDimensions()->getSize());
    }

    void
    getProperties(std::map<std::string, std::string> & collectedProperties) const
    {
234
      shared_ptr<const XdmfArray> dimensions = mRegularGrid->getDimensions();
235 236 237 238 239 240 241
      if(dimensions->getSize() == 3){
        collectedProperties["Type"] = "3DCoRectMesh";
      }
      else if(dimensions->getSize() == 2) {
        collectedProperties["Type"] = "2DCoRectMesh";
      }
      else {
242 243 244
        XdmfError::message(XdmfError::FATAL, 
                           "Dimensions not 2 or 3 in "
                           "XdmfTopologyTypeRegular::getProperties");
245 246 247 248 249 250 251
      }
      collectedProperties["Dimensions"] = dimensions->getValuesString();
    }

  private:

    XdmfTopologyTypeRegular(const XdmfRegularGrid * const regularGrid) :
252
      XdmfTopologyType(0, 0, std::vector<shared_ptr<const XdmfTopologyType> >(), 0, "foo", XdmfTopologyType::Structured, 0x1102),
253 254 255 256 257 258 259 260
      mRegularGrid(regularGrid)
    {
    }

    const XdmfRegularGrid * const mRegularGrid;

  };

261 262 263
  XdmfRegularGridImpl(const shared_ptr<XdmfArray> brickSize,
                      const shared_ptr<XdmfArray> numPoints,
                      const shared_ptr<XdmfArray> origin) :
264 265 266 267 268 269
    mBrickSize(brickSize),
    mDimensions(numPoints),
    mOrigin(origin)
  {
  }

270 271 272
  shared_ptr<XdmfArray> mBrickSize;
  shared_ptr<XdmfArray> mDimensions;
  shared_ptr<XdmfArray> mOrigin;
273 274 275

};

276
shared_ptr<XdmfRegularGrid>
277 278 279 280 281 282
XdmfRegularGrid::New(const double xBrickSize,
                     const double yBrickSize,
                     const unsigned int xNumPoints,
                     const unsigned int yNumPoints,
                     const double xOrigin,
                     const double yOrigin)
283
{
284
  shared_ptr<XdmfArray> brickSize = XdmfArray::New();
285 286 287
  brickSize->resize<double>(2);
  brickSize->insert(0, xBrickSize);
  brickSize->insert(1, yBrickSize);
288
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
289 290 291
  numPoints->resize<unsigned int>(2);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
292
  shared_ptr<XdmfArray> origin = XdmfArray::New();
293 294 295
  origin->resize<double>(2);
  origin->insert(0, xOrigin);
  origin->insert(1, yOrigin);
296 297 298
  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
                                                    numPoints,
                                                    origin));
299
  return p;
300 301
}

302
shared_ptr<XdmfRegularGrid>
303 304 305 306 307 308 309 310 311
XdmfRegularGrid::New(const double xBrickSize,
                     const double yBrickSize,
                     const double zBrickSize,
                     const unsigned int xNumPoints,
                     const unsigned int yNumPoints,
                     const unsigned int zNumPoints,
                     const double xOrigin,
                     const double yOrigin,
                     const double zOrigin)
312
{
313
  shared_ptr<XdmfArray> brickSize = XdmfArray::New();
314 315 316 317
  brickSize->resize<double>(3);
  brickSize->insert(0, xBrickSize);
  brickSize->insert(1, yBrickSize);
  brickSize->insert(2, zBrickSize);
318
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
319 320 321 322
  numPoints->resize<unsigned int>(3);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
  numPoints->insert(2, zNumPoints);
323
  shared_ptr<XdmfArray> origin = XdmfArray::New();
324 325 326 327
  origin->resize<double>(3);
  origin->insert(0, xOrigin);
  origin->insert(1, yOrigin);
  origin->insert(2, zOrigin);
328 329 330
  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
                                                    numPoints,
                                                    origin));
331
  return p;
332 333
}

334 335 336 337
shared_ptr<XdmfRegularGrid>
XdmfRegularGrid::New(const shared_ptr<XdmfArray> brickSize,
                     const shared_ptr<XdmfArray> numPoints,
                     const shared_ptr<XdmfArray> origin)
338
{
339 340 341
  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
                                                    numPoints,
                                                    origin));
342
  return p;
343 344
}

345 346 347
XdmfRegularGrid::XdmfRegularGrid(const shared_ptr<XdmfArray> brickSize,
                                 const shared_ptr<XdmfArray> numPoints,
                                 const shared_ptr<XdmfArray> origin) :
348 349 350
  XdmfGrid(XdmfRegularGridImpl::XdmfGeometryRegular::New(this),
           XdmfRegularGridImpl::XdmfTopologyRegular::New(this)),
  mImpl(new XdmfRegularGridImpl(brickSize, numPoints, origin))
351 352 353
{
}

354
XdmfRegularGrid::~XdmfRegularGrid()
355
{
356
  delete mImpl;
357 358
}

359
const std::string XdmfRegularGrid::ItemTag = "Grid";
360

361
shared_ptr<XdmfArray>
362
XdmfRegularGrid::getBrickSize()
363
{
364 365
  return boost::const_pointer_cast<XdmfArray>
    (static_cast<const XdmfRegularGrid &>(*this).getBrickSize());
366 367
}

368
shared_ptr<const XdmfArray>
369
XdmfRegularGrid::getBrickSize() const
370
{
371
  return mImpl->mBrickSize;
372 373
}

374
shared_ptr<XdmfArray>
375
XdmfRegularGrid::getDimensions()
376
{
377 378
  return boost::const_pointer_cast<XdmfArray>
    (static_cast<const XdmfRegularGrid &>(*this).getDimensions());
379 380
}

381
shared_ptr<const XdmfArray>
382
XdmfRegularGrid::getDimensions() const
383
{
384
  return mImpl->mDimensions;
385 386
}

387
shared_ptr<XdmfArray>
388
XdmfRegularGrid::getOrigin()
389
{
390 391
  return boost::const_pointer_cast<XdmfArray>
    (static_cast<const XdmfRegularGrid &>(*this).getOrigin());
392 393
}

394
shared_ptr<const XdmfArray>
395
XdmfRegularGrid::getOrigin() const
396
{
397
  return mImpl->mOrigin;
398 399
}

400 401
void
XdmfRegularGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
402
                              const std::vector<shared_ptr<XdmfItem> > & childItems,
403
                              const XdmfCoreReader * const reader)
404
{
405 406
  XdmfGrid::populateItem(itemProperties, childItems, reader);

407
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
408 409 410
        childItems.begin();
      iter != childItems.end();
      ++iter) {
411 412
    if(shared_ptr<XdmfRegularGrid> regularGrid =
       shared_dynamic_cast<XdmfRegularGrid>(*iter)) {
413 414 415 416 417 418 419 420 421 422 423 424 425
      if(regularGrid->getBrickSize()) {
        mImpl->mBrickSize = regularGrid->getBrickSize();
      }

      if(regularGrid->getDimensions()) {
        mImpl->mDimensions = regularGrid->getDimensions();
      }

      if(regularGrid->getOrigin()) {
        mImpl->mOrigin = regularGrid->getOrigin();
      }
    }
  }
426 427
}

428
void
429
XdmfRegularGrid::setBrickSize(const shared_ptr<XdmfArray> brickSize)
430
{
431
  mImpl->mBrickSize = brickSize;
432 433
}

434
void
435
XdmfRegularGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
436
{
437
  mImpl->mDimensions = dimensions;
438 439
}

440
void
441
XdmfRegularGrid::setOrigin(const shared_ptr<XdmfArray> origin)
442
{
443
  mImpl->mOrigin = origin;
444
}