XdmfRegularGrid.cpp 9.14 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * XdmfGridRegular.cpp
 *
 *  Created on: Jan 25, 2010
 *      Author: kleiter
 */

#include <cmath>
#include "XdmfArray.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfGeometryType.hpp"
12
#include "XdmfRegularGrid.hpp"
13 14 15 16 17 18
#include "XdmfTopology.hpp"
#include "XdmfTopologyType.hpp"

/**
 * PIMPL
 */
19
class XdmfRegularGrid::XdmfRegularGridImpl {
20 21 22 23 24 25 26 27

public:

	class XdmfGeometryRegular : public XdmfGeometry
	{

	public:

28
		static boost::shared_ptr<XdmfGeometryRegular> New(XdmfRegularGrid * const regularGrid)
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
		{
			boost::shared_ptr<XdmfGeometryRegular> p(new XdmfGeometryRegular(regularGrid));
			return p;
		}

		unsigned int getNumberPoints() const
		{
			const boost::shared_ptr<const XdmfArray> dimensions = 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 traverse(const boost::shared_ptr<XdmfBaseVisitor> visitor)
		{
			boost::shared_ptr<XdmfArray> origin = mRegularGrid->getOrigin();
			boost::shared_ptr<XdmfArray> brickSize = mRegularGrid->getBrickSize();
			origin->accept(visitor);
			brickSize->accept(visitor);
		}

	private:

59
		XdmfGeometryRegular(XdmfRegularGrid * const regularGrid) :
60 61
			mRegularGrid(regularGrid)
		{
62
			this->setType(XdmfGeometryTypeRegular::New(mRegularGrid));
63 64
		}

65
		XdmfRegularGrid * const mRegularGrid;
66 67 68 69 70 71 72
	};

	class XdmfGeometryTypeRegular : public XdmfGeometryType
	{

	public:

73
		static boost::shared_ptr<const XdmfGeometryTypeRegular> New(const XdmfRegularGrid * const regularGrid)
74 75 76 77 78 79 80 81 82 83 84 85
		{
			boost::shared_ptr<const XdmfGeometryTypeRegular> p(new XdmfGeometryTypeRegular(regularGrid));
			return p;
		}

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

		void getProperties(std::map<std::string, std::string> & collectedProperties) const
		{
86 87
			const unsigned int dimensions = this->getDimensions();
			if(dimensions == 3)
88 89 90
			{
				collectedProperties["Type"] = "ORIGIN_DXDYDZ";
			}
91
			else if(dimensions == 2)
92 93 94 95 96 97 98 99 100 101 102
			{
				collectedProperties["Type"] = "ORIGIN_DXDY";
			}
			else
			{
				assert(false);
			}
		}

	private:

103
		XdmfGeometryTypeRegular(const XdmfRegularGrid * const regularGrid) :
104 105 106 107 108
			XdmfGeometryType("", 0),
			mRegularGrid(regularGrid)
		{
		}

109
		const XdmfRegularGrid * const mRegularGrid;
110 111 112 113 114 115 116 117

	};

	class XdmfTopologyRegular : public XdmfTopology
	{

	public:

118
		static boost::shared_ptr<XdmfTopologyRegular> New(const XdmfRegularGrid * const regularGrid)
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
		{
			boost::shared_ptr<XdmfTopologyRegular> p(new XdmfTopologyRegular(regularGrid));
			return p;
		}

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

141
		XdmfTopologyRegular(const XdmfRegularGrid * const regularGrid) :
142 143 144 145 146
			mRegularGrid(regularGrid)
		{
			this->setType(XdmfTopologyTypeRegular::New(regularGrid));
		}

147
		const XdmfRegularGrid * const mRegularGrid;
148 149 150 151 152 153 154
	};

	class XdmfTopologyTypeRegular : public XdmfTopologyType
	{

	public:

155
		static boost::shared_ptr<const XdmfTopologyTypeRegular> New(const XdmfRegularGrid * const regularGrid)
156 157 158 159 160 161 162
		{
			boost::shared_ptr<const XdmfTopologyTypeRegular> p(new XdmfTopologyTypeRegular(regularGrid));
			return p;
		}

		unsigned int getNodesPerElement() const
		{
163
			// 2^Dimensions
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
			// 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
		{
			boost::shared_ptr<const XdmfArray> dimensions = mRegularGrid->getDimensions();
			if(dimensions->getSize() == 3)
			{
				collectedProperties["Type"] = "3DCoRectMesh";
			}
			else if(dimensions->getSize() == 2)
			{
				collectedProperties["Type"] = "2DCoRectMesh";
			}
			else
			{
				assert(false);
			}
			collectedProperties["Dimensions"] = dimensions->getValuesString();
		}

	private:

188
		XdmfTopologyTypeRegular(const XdmfRegularGrid * const regularGrid) :
189
			XdmfTopologyType(0, "foo", XdmfTopologyType::Structured, 0x1102),
190 191 192 193
			mRegularGrid(regularGrid)
		{
		}

194
		const XdmfRegularGrid * const mRegularGrid;
195 196 197

	};

198
	XdmfRegularGridImpl(const boost::shared_ptr<XdmfArray> brickSize, const boost::shared_ptr<XdmfArray> numPoints, const boost::shared_ptr<XdmfArray> origin) :
199 200 201
		mBrickSize(brickSize),
		mDimensions(numPoints),
		mOrigin(origin)
202 203 204 205 206 207 208 209 210
	{
	}

	boost::shared_ptr<XdmfArray> mBrickSize;
	boost::shared_ptr<XdmfArray> mDimensions;
	boost::shared_ptr<XdmfArray> mOrigin;

};

211
boost::shared_ptr<XdmfRegularGrid> XdmfRegularGrid::New(const double xBrickSize, const double yBrickSize, const unsigned int xNumPoints,
212
	const unsigned int yNumPoints, const double xOrigin, const double yOrigin)
213
{
214 215
	boost::shared_ptr<XdmfArray> brickSize = XdmfArray::New();
	brickSize->resize<double>(2);
216 217
	brickSize->insert(0, xBrickSize);
	brickSize->insert(1, yBrickSize);
218 219
	boost::shared_ptr<XdmfArray> numPoints = XdmfArray::New();
	numPoints->resize<unsigned int>(2);
220 221
	numPoints->insert(0, xNumPoints);
	numPoints->insert(1, yNumPoints);
222 223
	boost::shared_ptr<XdmfArray> origin = XdmfArray::New();
	origin->resize<double>(2);
224 225
	origin->insert(0, xOrigin);
	origin->insert(1, yOrigin);
226
	boost::shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize, numPoints, origin));
227 228 229
	return p;
}

230
boost::shared_ptr<XdmfRegularGrid> XdmfRegularGrid::New(const double xBrickSize, const double yBrickSize, const double zBrickSize,
231 232
	const unsigned int xNumPoints, const unsigned int yNumPoints, const unsigned int zNumPoints,
	const double xOrigin, const double yOrigin, const double zOrigin)
233
{
234 235
	boost::shared_ptr<XdmfArray> brickSize = XdmfArray::New();
	brickSize->resize<double>(3);
236 237 238
	brickSize->insert(0, xBrickSize);
	brickSize->insert(1, yBrickSize);
	brickSize->insert(2, zBrickSize);
239 240
	boost::shared_ptr<XdmfArray> numPoints = XdmfArray::New();
	numPoints->resize<unsigned int>(3);
241 242 243
	numPoints->insert(0, xNumPoints);
	numPoints->insert(1, yNumPoints);
	numPoints->insert(2, zNumPoints);
244 245
	boost::shared_ptr<XdmfArray> origin = XdmfArray::New();
	origin->resize<double>(3);
246 247 248
	origin->insert(0, xOrigin);
	origin->insert(1, yOrigin);
	origin->insert(2, zOrigin);
249
	boost::shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize, numPoints, origin));
250 251 252
	return p;
}

253
boost::shared_ptr<XdmfRegularGrid> XdmfRegularGrid::New(const boost::shared_ptr<XdmfArray> brickSize, const boost::shared_ptr<XdmfArray> numPoints,
254
		const boost::shared_ptr<XdmfArray> origin)
255
{
256
	boost::shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize, numPoints, origin));
257
	return p;
258 259
}

260
XdmfRegularGrid::XdmfRegularGrid(const boost::shared_ptr<XdmfArray> brickSize, const boost::shared_ptr<XdmfArray> numPoints,
261
	const boost::shared_ptr<XdmfArray> origin) :
262 263
	XdmfGrid(XdmfRegularGridImpl::XdmfGeometryRegular::New(this), XdmfRegularGridImpl::XdmfTopologyRegular::New(this)),
	mImpl(new XdmfRegularGridImpl(brickSize, numPoints, origin))
264 265 266
{
}

267
XdmfRegularGrid::~XdmfRegularGrid()
268 269 270 271
{
	delete mImpl;
}

272
const std::string XdmfRegularGrid::ItemTag = "Grid";
273

274
boost::shared_ptr<XdmfArray> XdmfRegularGrid::getBrickSize()
275
{
276
	return boost::const_pointer_cast<XdmfArray>(static_cast<const XdmfRegularGrid &>(*this).getBrickSize());
277 278
}

279
boost::shared_ptr<const XdmfArray> XdmfRegularGrid::getBrickSize() const
280 281 282 283
{
	return mImpl->mBrickSize;
}

284
boost::shared_ptr<XdmfArray> XdmfRegularGrid::getDimensions()
285
{
286
	return boost::const_pointer_cast<XdmfArray>(static_cast<const XdmfRegularGrid &>(*this).getDimensions());
287 288
}

289
boost::shared_ptr<const XdmfArray> XdmfRegularGrid::getDimensions() const
290 291 292 293
{
	return mImpl->mDimensions;
}

294
boost::shared_ptr<XdmfArray> XdmfRegularGrid::getOrigin()
295
{
296
	return boost::const_pointer_cast<XdmfArray>(static_cast<const XdmfRegularGrid &>(*this).getOrigin());
297 298
}

299
boost::shared_ptr<const XdmfArray> XdmfRegularGrid::getOrigin() const
300 301 302 303
{
	return mImpl->mOrigin;
}

304
void XdmfRegularGrid::populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems, const XdmfCoreReader * const reader)
305 306
{
	XdmfGrid::populateItem(itemProperties, childItems, reader);
307 308

	for(std::vector<boost::shared_ptr<XdmfItem> >::const_iterator iter = childItems.begin(); iter != childItems.end(); ++iter)
309
	{
310
		if(boost::shared_ptr<XdmfRegularGrid> regularGrid = boost::shared_dynamic_cast<XdmfRegularGrid>(*iter))
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
		{
			if(regularGrid->getBrickSize())
			{
				mImpl->mBrickSize = regularGrid->getBrickSize();
			}

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

			if(regularGrid->getOrigin())
			{
				mImpl->mOrigin = regularGrid->getOrigin();
			}
		}
327 328 329
	}
}

330
void XdmfRegularGrid::setBrickSize(const boost::shared_ptr<XdmfArray> brickSize)
331 332 333 334
{
	mImpl->mBrickSize = brickSize;
}

335
void XdmfRegularGrid::setDimensions(const boost::shared_ptr<XdmfArray> dimensions)
336 337 338 339
{
	mImpl->mDimensions = dimensions;
}

340
void XdmfRegularGrid::setOrigin(const boost::shared_ptr<XdmfArray> origin)
341 342 343
{
	mImpl->mOrigin = origin;
}