XdmfCurvilinearGrid.cpp 14.8 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 : public XdmfGridImpl {
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 55 56
    bool isInitialized() const
    {
      return true;
    }

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
      this->setType(XdmfTopologyTypeCurvilinear::New(curvilinearGrid));
78 79 80 81 82 83 84 85 86 87
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;
  };

  class XdmfTopologyTypeCurvilinear : public XdmfTopologyType
  {

  public:

88
    static shared_ptr<const XdmfTopologyTypeCurvilinear>
89 90
    New(const XdmfCurvilinearGrid * const curvilinearGrid)
    {
91
      shared_ptr<const XdmfTopologyTypeCurvilinear>
92 93 94 95
        p(new XdmfTopologyTypeCurvilinear(curvilinearGrid));
      return p;
    }

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

    unsigned int
    getFacesPerElement() const
    {
124 125
      return calculateHypercubeNumElements(mCurvilinearGrid->getDimensions()->getSize(), 2);
/*
126 127
      const unsigned int dimensions = 
        mCurvilinearGrid->getDimensions()->getSize();
128 129 130 131
      if (dimensions == 1) {
        return 0;
      }
      else if(dimensions == 2) {
132 133 134 135 136 137
        return 1;
      }
      else if(dimensions == 3) {
        return 6;
      }
      else {
138 139 140
        XdmfError::message(XdmfError::FATAL, 
                           "Grid dimensions not 2 or 3 in "
                           "XdmfTopologyTypeCurvilinear::getFacesPerElement");
141 142
      }
      return 0;
143
*/
144 145
    }

146 147 148
    unsigned int
    getNodesPerElement() const
    {
149
      return calculateHypercubeNumElements(mCurvilinearGrid->getDimensions()->getSize(), 0);
150 151
      // 2^Dimensions
      // e.g. 1D = 2 nodes per element and 2D = 4 nodes per element.
152 153
//      return (unsigned int)
//        std::pow(2, (double)mCurvilinearGrid->getDimensions()->getSize());
154 155 156 157 158
    }

    void
    getProperties(std::map<std::string, std::string> & collectedProperties) const
    {
159
      shared_ptr<const XdmfArray> dimensions =
160 161 162 163 164 165 166 167
        mCurvilinearGrid->getDimensions();
      if(dimensions->getSize() == 3) {
        collectedProperties["Type"] = "3DSMesh";
      }
      else if(dimensions->getSize() == 2) {
        collectedProperties["Type"] = "2DSMesh";
      }
      else {
168 169 170 171
        collectedProperties["Type"] = "SMesh";
//        XdmfError::message(XdmfError::FATAL, 
//                           "Grid dimensions not 2 or 3 in "
//                           "XdmfTopologyTypeCurvilinear::getProperties");
172 173 174 175 176 177 178
      }
      collectedProperties["Dimensions"] = dimensions->getValuesString();
    }

  private:

    XdmfTopologyTypeCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
179 180 181 182 183 184 185
      XdmfTopologyType(0,
                       0,
                       std::vector<shared_ptr<const XdmfTopologyType> >(),
                       0,
                       "foo",
                       XdmfTopologyType::Structured,
                       0x1110),
186 187 188 189 190 191 192 193
      mCurvilinearGrid(curvilinearGrid)
    {
    }

    const XdmfCurvilinearGrid * const mCurvilinearGrid;

  };

194
  XdmfCurvilinearGridImpl(const shared_ptr<XdmfArray> numPoints) :
195 196
    mDimensions(numPoints)
  {
197
     mGridType ="Curvilinear";
198
  }
199

200 201 202 203
  XdmfGridImpl * duplicate()
  {
    return new XdmfCurvilinearGridImpl(mDimensions);
  }
204

205
  shared_ptr<XdmfArray> mDimensions;
206 207
};

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

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

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

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

XdmfCurvilinearGrid::XdmfCurvilinearGrid(XdmfCurvilinearGrid & refGrid) :
  XdmfGrid(refGrid)
250
{
251
  mTopology = XdmfCurvilinearGridImpl::XdmfTopologyCurvilinear::New(this);
252 253
}

254
XdmfCurvilinearGrid::~XdmfCurvilinearGrid()
255
{
256 257 258 259
  if (mImpl) {
    delete mImpl;
  }
  mImpl = NULL;
260 261
}

262
const std::string XdmfCurvilinearGrid::ItemTag = "Grid";
263

264 265 266 267
void
XdmfCurvilinearGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
{
  XdmfGrid::copyGrid(sourceGrid);
268
  if (shared_ptr<XdmfCurvilinearGrid> classedGrid = shared_dynamic_cast<XdmfCurvilinearGrid>(sourceGrid))
269 270 271 272 273 274 275
  {
    // Copy stucture from read grid to this grid
    this->setGeometry(classedGrid->getGeometry());
    this->setDimensions(classedGrid->getDimensions());
  }
}

276
shared_ptr<XdmfArray>
277
XdmfCurvilinearGrid::getDimensions()
278
{
279
  return boost::const_pointer_cast<XdmfArray>
280
    (static_cast<const XdmfCurvilinearGrid &>(*this).getDimensions());
281 282
}

283
shared_ptr<const XdmfArray>
284
XdmfCurvilinearGrid::getDimensions() const
285
{
286
  return ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions;
287 288
}

289
shared_ptr<XdmfGeometry>
290
XdmfCurvilinearGrid::getGeometry()
291
{
292
  return boost::const_pointer_cast<XdmfGeometry>
293
    (static_cast<const XdmfGrid &>(*this).getGeometry());
294 295
}

296 297
void
XdmfCurvilinearGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
298
                                  const std::vector<shared_ptr<XdmfItem> > & childItems,
299
                                  const XdmfCoreReader * const reader)
300
{
301 302
  XdmfGrid::populateItem(itemProperties, childItems, reader);

303
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
304 305 306
        childItems.begin();
      iter != childItems.end();
      ++iter) {
307 308
    if(shared_ptr<XdmfCurvilinearGrid> curvilinearGrid =
       shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
309 310 311 312 313 314 315 316 317 318
      ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions = curvilinearGrid->getDimensions();
    }
  }
}

void
XdmfCurvilinearGrid::read()
{
  if (mGridController)
  {
319 320
    if (shared_ptr<XdmfCurvilinearGrid> grid = shared_dynamic_cast<XdmfCurvilinearGrid>(mGridController->read()))
    { 
321 322 323
      // Copy stucture from read grid to this grid
      copyGrid(grid);
    }
324
    else if (shared_dynamic_cast<XdmfGrid>(mGridController->read()))
325
    {
326 327
      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
    }
328 329
    else
    {
330
      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
331 332
    }
  }
333 334
}

335 336 337 338 339 340 341 342
void
XdmfCurvilinearGrid::release()
{
  XdmfGrid::release();
  this->setGeometry(shared_ptr<XdmfGeometry>());
  this->setDimensions(shared_ptr<XdmfArray>());
}

343
void
344
XdmfCurvilinearGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
345
{
346
  ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions = dimensions;
347
  this->setIsChanged(true);
348 349
}

350
void
351
XdmfCurvilinearGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
352
{
353
  mGeometry = geometry;
354 355 356 357 358 359 360 361
  this->setIsChanged(true);
}

// C Wrappers

XDMFCURVILINEARGRID * XdmfCurvilinearGridNew2D(unsigned int xNumPoints,
                                               unsigned int yNumPoints)
{
362 363 364 365 366 367 368 369 370 371
  try
  {
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
  catch (...)
  {
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
372 373 374 375 376 377
}

XDMFCURVILINEARGRID * XdmfCurvilinearGridNew3D(unsigned int xNumPoints,
                                               unsigned int yNumPoints,
                                               unsigned int zNumPoints)
{
378 379 380 381 382 383 384 385 386 387
  try
  {
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints, zNumPoints);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
  catch (...)
  {
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints, zNumPoints);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
388 389 390 391 392
}

XDMFCURVILINEARGRID * XdmfCurvilinearGridNew(XDMFARRAY * numPoints, int * status)
{
  XDMF_ERROR_WRAP_START(status)
393 394 395 396 397 398 399 400 401 402 403 404
  try
  {
    shared_ptr<XdmfArray> tempArray = shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter());
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(tempArray);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
  catch (...)
  {
    shared_ptr<XdmfArray> tempArray = shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter());
    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(tempArray);
    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
  }
405 406 407 408 409 410 411
  XDMF_ERROR_WRAP_END(status)
  return NULL;
}

XDMFARRAY * XdmfCurvilinearGridGetDimensions(XDMFCURVILINEARGRID * grid, int * status)
{
  XDMF_ERROR_WRAP_START(status)
412 413 414 415 416 417 418 419 420 421 422 423 424 425
  try
  {
    XdmfItem * classedPointer = (XdmfItem *)grid;
    XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
    shared_ptr<XdmfArray> generatedArray = gridPointer->getDimensions();
    return (XDMFARRAY *)((void *)generatedArray.get());
  }
  catch (...)
  {
    XdmfItem * classedPointer = (XdmfItem *)grid;
    XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
    shared_ptr<XdmfArray> generatedArray = gridPointer->getDimensions();
    return (XDMFARRAY *)((void *)generatedArray.get());
  }
426 427 428 429 430 431
  XDMF_ERROR_WRAP_END(status)
  return NULL;
}

XDMFGEOMETRY * XdmfCurvilinearGridGetGeometry(XDMFCURVILINEARGRID * grid)
{
432 433 434 435
  XdmfItem * classedPointer = (XdmfItem *)grid;
  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
  shared_ptr<XdmfGeometry> generatedGeometry = gridPointer->getGeometry();
  return (XDMFGEOMETRY *)((void *)generatedGeometry.get());
436 437 438 439 440
}

void XdmfCurvilinearGridSetDimensions(XDMFCURVILINEARGRID * grid, XDMFARRAY * dimensions, int passControl, int * status)
{
  XDMF_ERROR_WRAP_START(status)
441 442 443 444 445 446 447 448
  XdmfItem * classedPointer = (XdmfItem *)grid;
  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
  if (passControl) {
    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions));
  }
  else {
    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions, XdmfNullDeleter()));
  }
449 450 451 452 453
  XDMF_ERROR_WRAP_END(status)
}

void XdmfCurvilinearGridSetGeometry(XDMFCURVILINEARGRID * grid, XDMFGEOMETRY * geometry, int passControl)
{
454 455 456 457 458 459 460 461
  XdmfItem * classedPointer = (XdmfItem *)grid;
  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
  if (passControl) {
    gridPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry));
  }
  else {
    gridPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry, XdmfNullDeleter()));
  }
462 463
}

464 465
XDMF_ITEM_C_CHILD_WRAPPER(XdmfCurvilinearGrid, XDMFCURVILINEARGRID)
XDMF_GRID_C_CHILD_WRAPPER(XdmfCurvilinearGrid, XDMFCURVILINEARGRID)