XdmfRegularGrid.cpp 12.9 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
        XdmfError::message(XdmfError::FATAL, "Dimensions not 2 or 3 in XdmfGeometryTypeRegular::getProperties");
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
      }
    }

  private:

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

    const XdmfRegularGrid * const mRegularGrid;

  };

  class XdmfTopologyRegular : public XdmfTopology
  {

  public:

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

    unsigned int
    getNumberElements() const
    {
148
      const shared_ptr<const XdmfArray> dimensions = 
149 150 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
        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:

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

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

220 221 222 223 224 225 226 227 228 229 230 231
    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
    {
232
      shared_ptr<const XdmfArray> dimensions = mRegularGrid->getDimensions();
233 234 235 236 237 238 239
      if(dimensions->getSize() == 3){
        collectedProperties["Type"] = "3DCoRectMesh";
      }
      else if(dimensions->getSize() == 2) {
        collectedProperties["Type"] = "2DCoRectMesh";
      }
      else {
240 241 242
        XdmfError::message(XdmfError::FATAL, 
                           "Dimensions not 2 or 3 in "
                           "XdmfTopologyTypeRegular::getProperties");
243 244 245 246 247 248 249
      }
      collectedProperties["Dimensions"] = dimensions->getValuesString();
    }

  private:

    XdmfTopologyTypeRegular(const XdmfRegularGrid * const regularGrid) :
250
      XdmfTopologyType(0, 0, 0, "foo", XdmfTopologyType::Structured, 0x1102),
251 252 253 254 255 256 257 258
      mRegularGrid(regularGrid)
    {
    }

    const XdmfRegularGrid * const mRegularGrid;

  };

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

268 269 270
  shared_ptr<XdmfArray> mBrickSize;
  shared_ptr<XdmfArray> mDimensions;
  shared_ptr<XdmfArray> mOrigin;
271 272 273

};

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

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

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

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

352
XdmfRegularGrid::~XdmfRegularGrid()
353
{
354
  delete mImpl;
355 356
}

357
const std::string XdmfRegularGrid::ItemTag = "Grid";
358

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

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

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

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

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

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

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

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

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

      if(regularGrid->getOrigin()) {
        mImpl->mOrigin = regularGrid->getOrigin();
      }
    }
  }
424 425
}

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

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

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