Forked from
Core Modules / dune-common
11151 commits behind the upstream repository.
-
Oliver Sander authored
[[Imported from SVN: r917]]
Oliver Sander authored[[Imported from SVN: r917]]
amirameshwriter.cc 11.48 KiB
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#include <amiramesh/AmiraMesh.h>
#if _3
/** \todo Make sure that the grid is three-dimensional */
template<class GridType, class DiscFuncType>
void Dune::AmiraMeshWriter<GridType, DiscFuncType>::writeGrid(const GridType& grid,
const std::string& filename)
{
// Temporary: we write this level
int level = grid.maxlevel();
// Find out whether the grid contains only tetrahedra. If yes, then
// it is written in TetraGrid format. If not, it is written in
// hexagrid format.
bool containsOnlyTetrahedra = true;
typename GridType::template Traits<0>::LevelIterator element = grid.template lbegin<0>(level);
typename GridType::template Traits<0>::LevelIterator end = grid.template lend<0>(level);
for (; element!=end; ++element) {
if (element->geometry().type() != tetrahedron) {
containsOnlyTetrahedra = false;
break;
}
}
printf("This is the AmiraMesh writer!\n");
int maxVerticesPerElement = (containsOnlyTetrahedra) ? 4 : 8;
const int DIM = 3;
int noOfNodes = grid.size(level, 3);
int noOfElem = grid.size(level, 0);
int i;
// create amiramesh object
AmiraMesh am;
// write grid vertex coordinates
AmiraMesh::Location* geo_nodes = new AmiraMesh::Location("Nodes", noOfNodes);
am.insert(geo_nodes);
AmiraMesh::Data* geo_node_data = new AmiraMesh::Data("Coordinates", geo_nodes,
McPrimType::mc_float, DIM);
am.insert(geo_node_data);
typedef typename GridType::template Traits<3>::LevelIterator VertexIterator;
VertexIterator vertex = grid.template lbegin<DIM>(level);
VertexIterator endvertex = grid.template lend<DIM>(level);
for (; vertex!=endvertex; ++vertex)
{
int index = vertex->index();
FieldVector<double, 3> coords = vertex->geometry()[0];
((float*)geo_node_data->dataPtr())[3*index+0] = coords(0);
((float*)geo_node_data->dataPtr())[3*index+1] = coords(1);
((float*)geo_node_data->dataPtr())[3*index+2] = coords(2);
}
#if 0
// handle materials
HxParamBundle* materials = new HxParamBundle("Materials");
for (k=0; k<=maxSubDom; k++) {
char buffer[100];
sprintf(buffer, "Material%d", k);
HxParamBundle* newMaterial = new HxParamBundle(buffer);
HxParameter* newId = new HxParameter("Id", k);
newMaterial->insert(newId);
materials->insert(newMaterial);
}
am_geometry.parameters.insert(materials);
ncomp = 0;
for(i=0; i<NVECTYPES; i++)
ncomp = MAX(ncomp,VD_NCMPS_IN_TYPE(sol, i));
#endif
/* write element section to file */
AmiraMesh::Location* element_loc = NULL;
if (containsOnlyTetrahedra)
element_loc = new AmiraMesh::Location("Tetrahedra", noOfElem);
else
element_loc = new AmiraMesh::Location("Hexahedra", noOfElem);
am.insert(element_loc);
AmiraMesh::Data* element_data = new AmiraMesh::Data("Nodes", element_loc,
McPrimType::mc_int32, maxVerticesPerElement);
am.insert(element_data);
int *dPtr = (int*)element_data->dataPtr();
typedef typename GridType::template Traits<0>::LevelIterator ElementIterator;
ElementIterator element2 = grid.template lbegin<0>(level);
ElementIterator endelement = grid.template lend<0>(level);
for (i=0; element2!=endelement; ++element2, i++) {
switch (element2->geometry().type()) {
case hexahedron :
dPtr[i*maxVerticesPerElement+0] = element2->template subIndex<3>(0)+1;
dPtr[i*maxVerticesPerElement+1] = element2->template subIndex<3>(1)+1;
dPtr[i*maxVerticesPerElement+2] = element2->template subIndex<3>(3)+1;
dPtr[i*maxVerticesPerElement+3] = element2->template subIndex<3>(2)+1;
dPtr[i*maxVerticesPerElement+4] = element2->template subIndex<3>(4)+1;
dPtr[i*maxVerticesPerElement+5] = element2->template subIndex<3>(5)+1;
dPtr[i*maxVerticesPerElement+6] = element2->template subIndex<3>(7)+1;
dPtr[i*maxVerticesPerElement+7] = element2->template subIndex<3>(6)+1;
break;
default :
for (int j=0; j<element2->geometry().corners(); j++)
dPtr[i*maxVerticesPerElement+j] = element2->template subIndex<3>(j)+1;
// If the element has less than 8 vertices use the last value
// to fill up the remaining slots
for (int j=element2->geometry().corners(); j<maxVerticesPerElement; j++)
dPtr[i*maxVerticesPerElement+j] = dPtr[i*maxVerticesPerElement+element2->geometry().corners()-1];
}
}
// write material section to grid file
AmiraMesh::Data* element_materials = new AmiraMesh::Data("Materials", element_loc, McPrimType::mc_uint8, 1);
am.insert(element_materials);
// for(i=0; i<noOfElem; i++)
// ((unsigned char*)element_materials->dataPtr())[i] = SUBDOMAIN(elemList[i]);
for(i=0; i<noOfElem; i++)
((unsigned char*)element_materials->dataPtr())[i] = 0;
if(!am.write(filename.c_str(), 1))
DUNE_THROW(IOError, "Writing geometry file failed!");
std::cout << "Grid written successfully to: " << filename << std::endl;
}
#endif // #if _3
#ifdef _2
template<class GridType, class DiscFuncType>
void Dune::AmiraMeshWriter<GridType, DiscFuncType>::writeGrid(const GridType& grid,
const std::string& filename)
{
// Temporary: we write this level
int level = grid.maxlevel();
// Find out whether the grid contains only triangles. If yes, then
// it is written as a HxTriangularGrid. If not, it cannot be
// written (so far).
bool containsOnlyTetrahedra = true;
typename GridType::template Traits<0>::LevelIterator element = grid.template lbegin<0>(level);
typename GridType::template Traits<0>::LevelIterator end = grid.template lend<0>(level);
for (; element!=end; ++element) {
if (element->geometry().type() != triangle) {
containsOnlyTetrahedra = false;
break;
}
}
printf("This is the 2D AmiraMesh writer!\n");
int maxVerticesPerElement = (containsOnlyTetrahedra) ? 3 : 4;
const int DIM = 2;
int noOfNodes = grid.size(level, DIM);
int noOfElem = grid.size(level, 0);
printf("noOfNodes %d, nodeOfElem: %d\n", noOfNodes, noOfElem);
int i;
//int tl, k, noOfBndTri, MarkKey, ncomp, maxSubDom;
std::string solFilename;
// Construct the name for the geometry file
std::string geoFilename(filename);
geoFilename += ".am";
// create amiramesh object
AmiraMesh am_geometry;
// Set the appropriate content type
am_geometry.parameters.set("ContentType", "HxTriangularGrid");
// write grid vertex coordinates
AmiraMesh::Location* geo_nodes = new AmiraMesh::Location("Nodes", noOfNodes);
am_geometry.insert(geo_nodes);
AmiraMesh::Data* geo_node_data = new AmiraMesh::Data("Coordinates", geo_nodes,
McPrimType::mc_float, DIM);
am_geometry.insert(geo_node_data);
typename GridType::template Traits<2>::LevelIterator vertex = grid.template lbegin<DIM>(level);
typename GridType::template Traits<2>::LevelIterator endvertex = grid.template lend<DIM>(level);
for (; vertex!=endvertex; ++vertex)
{
int index = vertex->index();
FieldVector<double, DIM> coords = vertex->geometry()[0];
((float*)geo_node_data->dataPtr())[2*index+0] = coords[0];
((float*)geo_node_data->dataPtr())[2*index+1] = coords[1];
}
#if 0
// handle materials
HxParamBundle* materials = new HxParamBundle("Materials");
for (k=0; k<=maxSubDom; k++) {
char buffer[100];
sprintf(buffer, "Material%d", k);
HxParamBundle* newMaterial = new HxParamBundle(buffer);
HxParameter* newId = new HxParameter("Id", k);
newMaterial->insert(newId);
materials->insert(newMaterial);
}
am_geometry.parameters.insert(materials);
ncomp = 0;
for(i=0; i<NVECTYPES; i++)
ncomp = MAX(ncomp,VD_NCMPS_IN_TYPE(sol, i));
#endif
/* write element section to geo - file */
AmiraMesh::Location* element_loc = NULL;
if (containsOnlyTetrahedra)
element_loc = new AmiraMesh::Location("Triangles", noOfElem);
else
element_loc = new AmiraMesh::Location("Quadrangles", noOfElem);
am_geometry.insert(element_loc);
AmiraMesh::Data* element_data = new AmiraMesh::Data("Nodes", element_loc,
McPrimType::mc_int32, maxVerticesPerElement);
am_geometry.insert(element_data);
//int *(dPtr[maxVerticesPerElement]) = (int*)element_data->dataPtr();
int *dPtr = (int*)element_data->dataPtr();
typename GridType::template Traits<0>::LevelIterator element2 = grid.template lbegin<0>(level);
typename GridType::template Traits<0>::LevelIterator endelement = grid.template lend<0>(level);
for (i=0; element2!=endelement; ++element2, i++) {
switch (element2->geometry().type()) {
default :
for (int j=0; j<element2->geometry().corners(); j++)
dPtr[i*maxVerticesPerElement+j] = element2->template subIndex<DIM>(j)+1;
// If the element has less than 8 vertices use the last value
// to fill up the remaining slots
for (int j=element2->geometry().corners(); j<maxVerticesPerElement; j++)
dPtr[i*maxVerticesPerElement+j] = dPtr[i*maxVerticesPerElement+element2->geometry().corners()-1];
}
}
// write material section to geo-file
AmiraMesh::Data* element_materials = new AmiraMesh::Data("Materials", element_loc, McPrimType::mc_uint8, 1);
am_geometry.insert(element_materials);
// for(i=0; i<noOfElem; i++)
// ((unsigned char*)element_materials->dataPtr())[i] = SUBDOMAIN(elemList[i]);
for(i=0; i<noOfElem; i++)
((unsigned char*)element_materials->dataPtr())[i] = 0;
if(!am_geometry.write(geoFilename.c_str(), 1))
DUNE_THROW(IOError, "Writing geometry file failed");
std::cout << "Grid written successfully to: " << geoFilename << std::endl;
}
#endif // #ifdef _2
template<class GridType, class DiscFuncType>
void Dune::AmiraMeshWriter<GridType, DiscFuncType>::writeFunction(const DiscFuncType& f,
const std::string& filename)
{
// Get grid type associated with DiscFuncType
typedef typename DiscFuncType::FunctionSpaceType FunctionSpaceType;
const GridType& grid = f.getFunctionSpace().getGrid();
const int level = grid.maxlevel();
const int noOfNodes = grid.size(level, GridType::dimension);
// temporary hack
const int ncomp = 1;
// Create AmiraMesh object
AmiraMesh am;
// Set the appropriate content type for 2D grid data
if (GridType::dimension==2)
am.parameters.set("ContentType", "HxTriangularData");
AmiraMesh::Location* sol_nodes = new AmiraMesh::Location("Nodes", noOfNodes);
am.insert(sol_nodes);
AmiraMesh::Data* nodeData = new AmiraMesh::Data("Data", sol_nodes, McPrimType::mc_double, ncomp);
am.insert(nodeData);
AmiraMesh::Field* nodeField = new AmiraMesh::Field(f.name().c_str(), ncomp, McPrimType::mc_double,
AmiraMesh::t_linear, nodeData);
am.insert(nodeField);
// write the data into the AmiraMesh object
typedef typename DiscFuncType::DofIteratorType DofIterator;
DofIterator dit = f.dbegin(level);
DofIterator ditend = f.dend(level);
int i=0;
for (; dit!=ditend; ++dit, i++) {
((double*)nodeData->dataPtr())[i] = *dit;
}
// actually save the solution file
// (the 1 means: ascii)
if (!am.write(filename.c_str(), 1) )
DUNE_THROW(IOError, "An error has occured writing file " << filename);
std::cout << "Solution written successfully to: " << filename << std::endl;
}