1 /*****************************************************************************/
2 /* XDMF */
3 /* eXtensible Data Model and Format */
4 /* */
5 /* Id : XdmfUnstructuredGrid.cpp */
6 /* */
7 /* Author: */
8 /* Kenneth Leiter */
9 /* kenneth.leiter@arl.army.mil */
10 /* US Army Research Laboratory */
11 /* Aberdeen Proving Ground, MD */
12 /* */
13 /* Copyright @ 2011 US Army Research Laboratory */
14 /* All Rights Reserved */
15 /* See Copyright.txt for details */
16 /* */
17 /* This software is distributed WITHOUT ANY WARRANTY; without */
18 /* even the implied warranty of MERCHANTABILITY or FITNESS */
19 /* FOR A PARTICULAR PURPOSE. See the above copyright notice */
20 /* for more information. */
21 /* */
22 /*****************************************************************************/
23
24 #include "XdmfError.hpp"
25 #include "XdmfGeometry.hpp"
26 #include "XdmfGeometryType.hpp"
27 #include "XdmfRegularGrid.hpp"
28 #include "XdmfTopology.hpp"
29 #include "XdmfTopologyType.hpp"
30 #include "XdmfUnstructuredGrid.hpp"
31
32 /**
33 * local functions
34 */
35 namespace {
36
37 void
convertRegularGeometry(unsigned int index,shared_ptr<XdmfArray> point,shared_ptr<XdmfArray> dimensions,shared_ptr<XdmfArray> brickSize,shared_ptr<XdmfArray> mGeometry)38 convertRegularGeometry(unsigned int index,
39 shared_ptr<XdmfArray> point,
40 shared_ptr<XdmfArray> dimensions,
41 shared_ptr<XdmfArray> brickSize,
42 shared_ptr<XdmfArray> mGeometry) {
43
44 const unsigned int nDim = dimensions->getValue<unsigned int>(index);
45 const double nBrickSize = brickSize->getValue<double>(index);
46 const double originalPoint = point->getValue<double>(index);
47
48 for(unsigned int i=0; i<nDim; ++i) {
49 if(index == 0) {
50 mGeometry->insert(mGeometry->getSize(),
51 point,
52 0,
53 point->getSize());
54 }
55 else {
56 convertRegularGeometry(index - 1,
57 point,
58 dimensions,
59 brickSize,
60 mGeometry);
61 }
62 const double currPoint = point->getValue<double>(index);
63 point->insert(index, currPoint + nBrickSize);
64 }
65
66 point->insert(index, originalPoint);
67 }
68
69 void
convertRegularTopology(shared_ptr<XdmfArray> dimensions,shared_ptr<XdmfArray> mTopology)70 convertRegularTopology(shared_ptr<XdmfArray> dimensions,
71 shared_ptr<XdmfArray> mTopology)
72 {
73
74 if(dimensions->getSize() == 2) {
75 const unsigned int nx = dimensions->getValue<unsigned int>(0);
76 const unsigned int ny = dimensions->getValue<unsigned int>(1);
77 unsigned int offset = 0;
78 for(unsigned int i=1; i<ny; ++i) {
79 for(unsigned int j=1; j<nx; ++j) {
80 mTopology->pushBack<unsigned int>(offset);
81 mTopology->pushBack<unsigned int>(offset + 1);
82 mTopology->pushBack<unsigned int>(offset + nx + 1);
83 mTopology->pushBack<unsigned int>(offset + nx);
84 ++offset;
85 }
86 ++offset;
87 }
88 }
89 else if(dimensions->getSize() == 3) {
90 const unsigned int nx = dimensions->getValue<unsigned int>(0);
91 const unsigned int ny = dimensions->getValue<unsigned int>(1);
92 const unsigned int nz = dimensions->getValue<unsigned int>(2);
93 const unsigned int zOffset = nx * ny;
94 unsigned int offset = 0;
95 for(unsigned int i=1; i<nz; ++i) {
96 for(unsigned int j=1; j<ny; ++j) {
97 for(unsigned int k=1; k<nx; ++k) {
98 mTopology->pushBack<unsigned int>(offset);
99 mTopology->pushBack<unsigned int>(offset + 1);
100 mTopology->pushBack<unsigned int>(offset + nx + 1);
101 mTopology->pushBack<unsigned int>(offset + nx);
102 mTopology->pushBack<unsigned int>(offset + zOffset);
103 mTopology->pushBack<unsigned int>(offset + zOffset + 1);
104 mTopology->pushBack<unsigned int>(offset + zOffset + nx + 1);
105 mTopology->pushBack<unsigned int>(offset + zOffset + nx);
106 ++offset;
107 }
108 ++offset;
109 }
110 offset += nx;
111 }
112 }
113 }
114 }
115
116 class XdmfUnstructuredGrid::XdmfUnstructuredGridImpl : public XdmfGridImpl
117 {
118 public:
XdmfUnstructuredGridImpl()119 XdmfUnstructuredGridImpl()
120 {
121 mGridType = "Unstructured";
122 }
123
~XdmfUnstructuredGridImpl()124 ~XdmfUnstructuredGridImpl()
125 {
126 }
127
duplicate()128 XdmfGridImpl * duplicate()
129 {
130 return new XdmfUnstructuredGridImpl();
131 }
132
getGridType() const133 std::string getGridType() const
134 {
135 return mGridType;
136 }
137 };
138
139 shared_ptr<XdmfUnstructuredGrid>
New()140 XdmfUnstructuredGrid::New()
141 {
142 shared_ptr<XdmfUnstructuredGrid> p(new XdmfUnstructuredGrid());
143 return p;
144 }
145
146 shared_ptr<XdmfUnstructuredGrid>
New(const shared_ptr<XdmfRegularGrid> regularGrid)147 XdmfUnstructuredGrid::New(const shared_ptr<XdmfRegularGrid> regularGrid)
148 {
149 shared_ptr<XdmfUnstructuredGrid> p(new XdmfUnstructuredGrid(regularGrid));
150 return p;
151 }
152
XdmfUnstructuredGrid()153 XdmfUnstructuredGrid::XdmfUnstructuredGrid() :
154 XdmfGrid(XdmfGeometry::New(), XdmfTopology::New())
155 {
156 mImpl = new XdmfUnstructuredGridImpl();
157 }
158
XdmfUnstructuredGrid(const shared_ptr<XdmfRegularGrid> regularGrid)159 XdmfUnstructuredGrid::XdmfUnstructuredGrid(const shared_ptr<XdmfRegularGrid> regularGrid) :
160 XdmfGrid(XdmfGeometry::New(), XdmfTopology::New())
161 {
162 mImpl = new XdmfUnstructuredGridImpl();
163
164 const shared_ptr<XdmfArray> origin = regularGrid->getOrigin();
165
166 shared_ptr<XdmfArray> brickSize = regularGrid->getBrickSize();
167 shared_ptr<XdmfArray> dimensions = regularGrid->getDimensions();
168
169 if(dimensions->getSize() != brickSize->getSize() ||
170 dimensions->getSize() != origin->getSize()) {
171 XdmfError::message(XdmfError::FATAL,
172 "Inconsistent brick, dimension, and origin sizes when"
173 "converting regular grid to unstructured grid in "
174 "XdmfUnstructuredGrid constructor");
175 }
176
177 bool releaseOrigin = false;
178 bool releaseBrickSize = false;
179 bool releaseDimensions = false;
180 if(!origin->isInitialized()) {
181 origin->read();
182 releaseOrigin = true;
183 }
184 if(!brickSize->isInitialized()) {
185 brickSize->read();
186 releaseBrickSize = true;
187 }
188 if(!dimensions->isInitialized()) {
189 dimensions->read();
190 releaseDimensions = true;
191 }
192
193 shared_ptr<const XdmfGeometryType> geometryType;
194 shared_ptr<const XdmfTopologyType> topologyType;
195 if(origin->getSize() == 2) {
196 geometryType = XdmfGeometryType::XY();
197 topologyType = XdmfTopologyType::Quadrilateral();
198 }
199 else if(origin->getSize() == 3) {
200 geometryType = XdmfGeometryType::XYZ();
201 topologyType = XdmfTopologyType::Hexahedron();
202 }
203 else {
204 XdmfError::message(XdmfError::FATAL,
205 "Cannot convert regular grid of dimensions not 2 or 3 "
206 "to XdmfUnstructuredGrid in XdmfUnstructuredGrid "
207 "constructor");
208 }
209 mGeometry->setType(geometryType);
210 mTopology->setType(topologyType);
211
212 shared_ptr<XdmfArray> point = XdmfArray::New();
213 point->insert(0, origin, 0, origin->getSize());
214 convertRegularGeometry(dimensions->getSize() - 1,
215 point,
216 dimensions,
217 brickSize,
218 mGeometry);
219 convertRegularTopology(dimensions,
220 mTopology);
221
222 if(releaseOrigin) {
223 origin->release();
224 }
225 if(releaseBrickSize) {
226 brickSize->release();
227 }
228 if(releaseDimensions) {
229 dimensions->release();
230 }
231 }
232
XdmfUnstructuredGrid(XdmfUnstructuredGrid & refGrid)233 XdmfUnstructuredGrid::XdmfUnstructuredGrid(XdmfUnstructuredGrid & refGrid) :
234 XdmfGrid(refGrid)
235 {
236 }
237
~XdmfUnstructuredGrid()238 XdmfUnstructuredGrid::~XdmfUnstructuredGrid()
239 {
240 if (mImpl) {
241 delete mImpl;
242 }
243 mImpl = NULL;
244 }
245
246 const std::string XdmfUnstructuredGrid::ItemTag = "Grid";
247
248 void
copyGrid(shared_ptr<XdmfGrid> sourceGrid)249 XdmfUnstructuredGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
250 {
251 XdmfGrid::copyGrid(sourceGrid);
252 if (shared_ptr<XdmfUnstructuredGrid> classedGrid = shared_dynamic_cast<XdmfUnstructuredGrid>(sourceGrid))
253 {
254 this->setGeometry(classedGrid->getGeometry());
255 this->setTopology(classedGrid->getTopology());
256 }
257 }
258
259 shared_ptr<XdmfGeometry>
getGeometry()260 XdmfUnstructuredGrid::getGeometry()
261 {
262 return boost::const_pointer_cast<XdmfGeometry>
263 (static_cast<const XdmfGrid &>(*this).getGeometry());
264 }
265
266 std::string
getItemTag() const267 XdmfUnstructuredGrid::getItemTag() const
268 {
269 return ItemTag;
270 }
271
272 shared_ptr<XdmfTopology>
getTopology()273 XdmfUnstructuredGrid::getTopology()
274 {
275 return boost::const_pointer_cast<XdmfTopology>
276 (static_cast<const XdmfGrid &>(*this).getTopology());
277 }
278
279 void
read()280 XdmfUnstructuredGrid::read()
281 {
282 if (mGridController)
283 {
284 if (shared_ptr<XdmfUnstructuredGrid> grid = shared_dynamic_cast<XdmfUnstructuredGrid>(mGridController->read()))
285 {
286 copyGrid(grid);
287 }
288 else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
289 {
290 XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
291 }
292 else
293 {
294 XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
295 }
296 }
297 }
298
299 void
release()300 XdmfUnstructuredGrid::release()
301 {
302 XdmfGrid::release();
303 this->setGeometry(shared_ptr<XdmfGeometry>());
304 this->setTopology(shared_ptr<XdmfTopology>());
305 }
306
307 void
setGeometry(const shared_ptr<XdmfGeometry> geometry)308 XdmfUnstructuredGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
309 {
310 mGeometry = geometry;
311 }
312
313 void
setTopology(const shared_ptr<XdmfTopology> topology)314 XdmfUnstructuredGrid::setTopology(const shared_ptr<XdmfTopology> topology)
315 {
316 mTopology = topology;
317 }
318
319 // C Wrappers
320
XdmfUnstructuredGridNew()321 XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNew()
322 {
323 try
324 {
325 shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New();
326 return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
327 }
328 catch (...)
329 {
330 shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New();
331 return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
332 }
333 }
334
XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid,int * status)335 XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid, int * status)
336 {
337 XDMF_ERROR_WRAP_START(status)
338 try
339 {
340 // Here it works when classed directly to the grid type,
341 // in other cases this may not work.
342 XdmfItem * tempPointer = (XdmfItem *)regularGrid;
343 XdmfRegularGrid * classedPointer = dynamic_cast<XdmfRegularGrid *>(tempPointer);
344 shared_ptr<XdmfRegularGrid> originGrid = shared_ptr<XdmfRegularGrid>(classedPointer, XdmfNullDeleter());
345 shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New(originGrid);
346 return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
347 }
348 catch (...)
349 {
350 // Here it works when classed directly to the grid type,
351 // in other cases this may not work.
352 XdmfItem * tempPointer = (XdmfItem *)regularGrid;
353 XdmfRegularGrid * classedPointer = dynamic_cast<XdmfRegularGrid *>(tempPointer);
354 shared_ptr<XdmfRegularGrid> originGrid = shared_ptr<XdmfRegularGrid>(classedPointer, XdmfNullDeleter());
355 shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New(originGrid);
356 return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
357 }
358 XDMF_ERROR_WRAP_END(status)
359 return NULL;
360 }
361
XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid)362 XDMFGEOMETRY * XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid)
363 {
364 XdmfItem * tempPointer = (XdmfItem *)grid;
365 XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
366 return (XDMFGEOMETRY *)((void *)(classedPointer->getGeometry().get()));
367 }
368
XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid)369 XDMFTOPOLOGY * XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid)
370 {
371 XdmfItem * tempPointer = (XdmfItem *)grid;
372 XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
373 return (XDMFTOPOLOGY *)((void *)(classedPointer->getTopology().get()));
374 }
375
XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid,XDMFGEOMETRY * geometry,int passControl)376 void XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid, XDMFGEOMETRY * geometry, int passControl)
377 {
378 XdmfItem * tempPointer = (XdmfItem *)grid;
379 XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
380 if (passControl) {
381 classedPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry));
382 }
383 else {
384 classedPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry, XdmfNullDeleter()));
385 }
386 }
387
XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid,XDMFTOPOLOGY * topology,int passControl)388 void XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid, XDMFTOPOLOGY * topology, int passControl)
389 {
390 XdmfItem * tempPointer = (XdmfItem *)grid;
391 XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
392 if (passControl) {
393 classedPointer->setTopology(shared_ptr<XdmfTopology>((XdmfTopology *)topology));
394 }
395 else {
396 classedPointer->setTopology(shared_ptr<XdmfTopology>((XdmfTopology *)topology, XdmfNullDeleter()));
397 }
398 }
399
400 XDMF_ITEM_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID)
401 XDMF_GRID_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID)
402