XdmfCurvilinearGrid.cpp 8.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 : 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 50 51 52 53 54
      try {
        shared_ptr<XdmfTopologyCurvilinear> 
          p(new XdmfTopologyCurvilinear(curvilinearGrid));
        return p;
      }
      catch (XdmfError e) {
        throw e;
      }
55 56 57 58 59
    }

    unsigned int
    getNumberElements() const
    {
60
      const shared_ptr<const XdmfArray> dimensions = 
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
        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)
    {
77 78 79 80 81 82
      try {
        this->setType(XdmfTopologyTypeCurvilinear::New(curvilinearGrid));
      }
      catch (XdmfError e) {
        throw e;
      }
83 84 85 86 87 88 89 90 91 92
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;
  };

  class XdmfTopologyTypeCurvilinear : public XdmfTopologyType
  {

  public:

93
    static shared_ptr<const XdmfTopologyTypeCurvilinear>
94 95
    New(const XdmfCurvilinearGrid * const curvilinearGrid)
    {
96
      shared_ptr<const XdmfTopologyTypeCurvilinear>
97 98 99 100
        p(new XdmfTopologyTypeCurvilinear(curvilinearGrid));
      return p;
    }

101 102 103 104 105 106 107 108 109 110 111 112
    unsigned int
    getEdgesPerElement() const
    {
      const unsigned int dimensions = 
        mCurvilinearGrid->getDimensions()->getSize();
      if(dimensions == 2) {
        return 4;
      }
      else if(dimensions == 3) {
        return 12;
      }
      else {
113 114 115 116 117 118 119 120
        try {
          XdmfError::message(XdmfError::FATAL, 
                             "Grid dimensions not 2 or 3 in "
                             "XdmfTopologyTypeCurvilinear::getEdgesPerElement");
        }
        catch (XdmfError e) {
          throw e;
        }
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
      }
      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 {
137 138 139 140 141 142 143 144
        try {
          XdmfError::message(XdmfError::FATAL, 
                             "Grid dimensions not 2 or 3 in "
                             "XdmfTopologyTypeCurvilinear::getFacesPerElement");
      }
      catch (XdmfError e) {
        throw e;
      }
145 146 147 148
      }
      return 0;
    }

149 150 151 152 153 154 155 156 157 158 159 160
    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
    {
161
      shared_ptr<const XdmfArray> dimensions =
162 163 164 165 166 167 168 169
        mCurvilinearGrid->getDimensions();
      if(dimensions->getSize() == 3) {
        collectedProperties["Type"] = "3DSMesh";
      }
      else if(dimensions->getSize() == 2) {
        collectedProperties["Type"] = "2DSMesh";
      }
      else {
170 171 172 173 174 175 176 177
        try {
          XdmfError::message(XdmfError::FATAL, 
                             "Grid dimensions not 2 or 3 in "
                             "XdmfTopologyTypeCurvilinear::getProperties");
        }
        catch (XdmfError e) {
          throw e;
        }
178 179 180 181 182 183 184
      }
      collectedProperties["Dimensions"] = dimensions->getValuesString();
    }

  private:

    XdmfTopologyTypeCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
185 186 187 188 189 190 191
      XdmfTopologyType(0,
                       0,
                       std::vector<shared_ptr<const XdmfTopologyType> >(),
                       0,
                       "foo",
                       XdmfTopologyType::Structured,
                       0x1110),
192 193 194 195 196 197 198 199
      mCurvilinearGrid(curvilinearGrid)
    {
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;

  };

200
  XdmfCurvilinearGridImpl(const shared_ptr<XdmfArray> numPoints) :
201 202 203 204
    mDimensions(numPoints)
  {
  }

205
  shared_ptr<XdmfArray> mDimensions;
206 207 208

};

209
shared_ptr<XdmfCurvilinearGrid>
210 211
XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
                         const unsigned int yNumPoints)
212
{
213
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
214 215 216
  numPoints->resize<unsigned int>(2);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
217
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
218
  return p;
219 220
}

221
shared_ptr<XdmfCurvilinearGrid>
222 223 224
XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
                         const unsigned int yNumPoints,
                         const unsigned int zNumPoints)
225
{
226
  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
227 228 229 230
  numPoints->resize<unsigned int>(3);
  numPoints->insert(0, xNumPoints);
  numPoints->insert(1, yNumPoints);
  numPoints->insert(2, zNumPoints);
231
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
232
  return p;
233 234
}

235 236
shared_ptr<XdmfCurvilinearGrid>
XdmfCurvilinearGrid::New(const shared_ptr<XdmfArray> numPoints)
237
{
238
  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
239
  return p;
240 241
}

242
XdmfCurvilinearGrid::XdmfCurvilinearGrid(const shared_ptr<XdmfArray> numPoints) :
243 244 245
  XdmfGrid(XdmfGeometry::New(),
           XdmfCurvilinearGridImpl::XdmfTopologyCurvilinear::New(this)),
  mImpl(new XdmfCurvilinearGridImpl(numPoints))
246 247 248
{
}

249
XdmfCurvilinearGrid::~XdmfCurvilinearGrid()
250
{
251
  delete mImpl;
252 253
}

254
const std::string XdmfCurvilinearGrid::ItemTag = "Grid";
255

256
shared_ptr<XdmfArray>
257
XdmfCurvilinearGrid::getDimensions()
258
{
259 260
  return boost::const_pointer_cast<XdmfArray>
    (static_cast<const XdmfCurvilinearGrid &>(*this).getDimensions());
261 262
}

263
shared_ptr<const XdmfArray>
264
XdmfCurvilinearGrid::getDimensions() const
265
{
266
  return mImpl->mDimensions;
267 268
}

269
shared_ptr<XdmfGeometry>
270
XdmfCurvilinearGrid::getGeometry()
271
{
272 273
  return boost::const_pointer_cast<XdmfGeometry>
    (static_cast<const XdmfGrid &>(*this).getGeometry());
274 275
}

276 277
void
XdmfCurvilinearGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
278
                                  const std::vector<shared_ptr<XdmfItem> > & childItems,
279
                                  const XdmfCoreReader * const reader)
280
{
281 282
  XdmfGrid::populateItem(itemProperties, childItems, reader);

283
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
284 285 286
        childItems.begin();
      iter != childItems.end();
      ++iter) {
287 288
    if(shared_ptr<XdmfCurvilinearGrid> curvilinearGrid =
       shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
289 290 291
      mImpl->mDimensions = curvilinearGrid->getDimensions();
    }
  }
292 293
}

294
void
295
XdmfCurvilinearGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
296
{
297
  mImpl->mDimensions = dimensions;
298 299
}

300
void
301
XdmfCurvilinearGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
302
{
303
  mGeometry = geometry;
304 305
}