From 946b8b3f4b5bb26091a4a557af61a240ab6c1185 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@dune-project.org> Date: Tue, 2 Mar 2004 11:15:05 +0000 Subject: [PATCH] I/O for the amiramesh format; no functionality so far [[Imported from SVN: r357]] --- lib/io/amirameshreader.hh | 50 ++++ lib/io/amirameshwriter.hh | 9 + lib/io/amuggridreader.cc | 470 ++++++++++++++++++++++++++++++++++++++ lib/io/amuggridwriter.cc | 316 +++++++++++++++++++++++++ 4 files changed, 845 insertions(+) create mode 100644 lib/io/amirameshreader.hh create mode 100644 lib/io/amuggridreader.cc create mode 100644 lib/io/amuggridwriter.cc diff --git a/lib/io/amirameshreader.hh b/lib/io/amirameshreader.hh new file mode 100644 index 000000000..111b7fe73 --- /dev/null +++ b/lib/io/amirameshreader.hh @@ -0,0 +1,50 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef __DUNE_AMIRAMESHREADER_HH__ +#define __DUNE_AMIRAMESHREADER_HH__ + +#include <string> +#include "../../common/array.hh" + +namespace Dune { + + /** @ingroup IO + * \brief Provides file reading facilities in the AmiraMesh format. + * + */ + template<class GRID, class T> + class AmiraMeshReader { + + public: + + /** \brief The method that does the writing. + * + * @param grid The grid objects that is to be written + * @param sol Data that should be written along with the grid + * @param filename The filename + */ + static void read(GRID& grid, + const std::string& filename); + + + AmiraMeshReader() {} + + }; + +} + +// Default implementation +template<class GRID, class T> +void Dune::AmiraMeshReader<GRID, T>::read(GRID& grid, + const std::string& filename) +{ + printf("No AmiraMesh reading has been implemented for this grid type!\n"); +} + + +// the amiramesh reader for UGGrid +#ifdef HAVE_UG +#include "amuggridreader.cc" +#endif + +#endif diff --git a/lib/io/amirameshwriter.hh b/lib/io/amirameshwriter.hh index 8e77764f5..a51c8bd2a 100644 --- a/lib/io/amirameshwriter.hh +++ b/lib/io/amirameshwriter.hh @@ -50,6 +50,15 @@ void Dune::AmiraMeshWriter<GRID, T>::write(const GRID& grid, printf("No AmiraMesh writing has been implemented for this grid type!\n"); } + +// the amiramesh writer for SimpleGrid +#ifndef __GNUC__ #include "amsimplegridwriter.cc" +#endif + +// the amiramesh writer for UGGrid +#ifdef HAVE_UG +#include "amuggridwriter.cc" +#endif #endif diff --git a/lib/io/amuggridreader.cc b/lib/io/amuggridreader.cc new file mode 100644 index 000000000..8bff05516 --- /dev/null +++ b/lib/io/amuggridreader.cc @@ -0,0 +1,470 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +// /////////////////////////////////////////////// +// Specialization of the AmiraMesh reader for UGGrid<3,3> +// /////////////////////////////////////////////// + +#include "../../grid/uggrid.hh" + +#include <amiramesh/AmiraMesh.h> +#include "../../../AmiraLibs/include/AmiraParamAccess.h" + +namespace Dune { + + template<> + class AmiraMeshReader<UGGrid<3,3>, double> { + + public: + + static void read(UGGrid<3,3>& grid, + const std::string& filename); + + static int CreateDomain(UGGrid<3,3>& grid, + const std::string& domainName, + const std::string& filename); + + AmiraMeshReader() {} + + }; + +} + + +// ////////////////////////////////////////////////// +// ////////////////////////////////////////////////// +static int SegmentDescriptionByAmira(void *data, double *param, double *result) +{ + + int triNum = * (int*) data; + + //printf("tri = %d, l0 = %5.5f, l1 = %5.5f\n", triNum, param[0], param[1]); + + double barCoords[2]; + double A[4] = {-1, 1, 0, -1}; + double b[2] = {1, 0}; + + // barCoords = A*param + b; + barCoords[0] = A[0]*param[0] + A[2]*param[1]; + barCoords[1] = A[1]*param[0] + A[3]*param[1]; + + barCoords[0] += b[0]; + barCoords[1] += b[1]; + + /* + An dieser Stelle wird vorausgesetzt, dass das bereits gesetzte Gebiet + nicht mehr geaendert wird + */ + //printf("barCoords: (%g %g)\n", barCoords[0], barCoords[1]); + + const float eps = 1e-6; + if (barCoords[0]<-eps || barCoords[1]<-eps || (1-barCoords[0]-barCoords[1])<-eps) { + printf("Illegal barycentric coordinate\n"); + assert(false); + } + + AmiraCallPositionParametrization(triNum, barCoords, result); + + return(0); +} + + +int Dune::AmiraMeshReader<Dune::UGGrid<3,3>, double>::CreateDomain(UGGrid<3,3>& grid, + const std::string& domainName, + const std::string& filename) +{ + const int DIM = 3; + const int MAX_CORNERS_OF_LINEAR_PATCH = DIM; + const int CORNERS_OF_BND_SEG = 4; + + + int point[CORNERS_OF_BND_SEG] = {-1, -1, -1, -1}; + double radius, MidPoint[3], alpha[2], beta[2], pos[3]; + + /* Alle Aufrufe an Deine Bibliothek beginnen mit "Amira" */ + + /* Load data */ + if(AmiraLoadMesh(domainName.c_str(), filename.c_str()) != AMIRA_OK) + { + UG3d::PrintErrorMessage('E', "CreateAmiraParametrization", "Domain not found"); + return(1); + } + + if(AmiraStartEditingDomain(domainName.c_str()) != AMIRA_OK) + { + UG3d::PrintErrorMessage('E', "AmiraStartEditing", "Domain not found"); + return(1); + } + + + /* Alle weiteren Anfragen an die Bibliothek beziehen sich jetzt auf das eben + geladen Gebiet. Maessig elegant, sollte aber gehen */ + + int noOfSegments = AmiraGetNoOfSegments(); + if(noOfSegments <= 0) + { + UG3d::PrintErrorMessage('E', "CreateAmiraDomain", "no segments found"); + return(1); + } + + int noOfNodes = AmiraGetNoOfNodes(); + if(noOfNodes <= 0) + { + UG3d::PrintErrorMessage('E', "CreateAmiraDomain", "no nodes found"); + return(1); + } + + + /* Das naechste ist neu. Wir brauchen eine Kugel, die das Gebiet komplett enthaelt. + Diese Information wird fuer die UG-Graphik benoetigt, die Kugel kann also durchaus + zu gross oder zu klein sein */ + + AmiraGetMidpointAndRadius(MidPoint, &radius); + + // printf("Amira radius = %5.2f, Midpoint = (%5.2f, %5.2f, %5.2f)\n", + // radius, MidPoint[0], MidPoint[1], MidPoint[2]); + + + /* Jetzt geht es an's eingemachte. Zuerst wird ein neues gebiet konstruiert und + in der internen UG Datenstruktur eingetragen */ + + bool isConvex = false; + + UG3d::domain* newDomain = UG3d::CreateDomain(const_cast<char*>(domainName.c_str()), + MidPoint, radius, + noOfSegments, noOfNodes, + isConvex ); + + + if (!newDomain) + return(1); + + + /* Alle weiteren Aufrufe von 'CreateBoundarySegment' beziehen sich jetzt auf das eben + erzeugte Gebiet */ + + + /* + alpha und beta spannen den Parameterbereich auf (s. beiliegendes .ps-file) + wenn ich das richtig verstehe, sollten die konstant sein fuer alle Segmente + */ + + alpha[0] = 0.0; + alpha[1] = 0.0; + beta[0] = 1.0; + beta[1] = 1.0; + + /* + Liste der Nummern der Randsegmente herstellen, wird als user data an das jeweilige + Segment weitergereicht + */ + + int* segmentIndexList = NULL; + segmentIndexList = (int*) ::malloc(noOfSegments*sizeof(int)); + + if(segmentIndexList == NULL) + return(1); + + for(int i = 0; i < noOfSegments; i++) { + + //std::string segmentName; + char segmentName[200]; + int left, right, j; + double coordinates[MAX_CORNERS_OF_LINEAR_PATCH][DIM]; + + AmiraGetNodeNumbersOfSegment(point, i); + + /* Es werden die Ecknummern eines Randsegmentes zurueckgegeben + point[0] = 0; point[1]=1; point[2]=2; point[3]=3; */ + + //segmentName = "AmiraSegment"; + if(sprintf(segmentName, "AmiraSegment %d", i) < 0) + return(1); + + /* left = innerRegion, right = outerRegion */ + AmiraGetLeftAndRightSideOfSegment(&left, &right, i); + + // printf("id = %d l = %d, r = %d\n", i, left, right); + // printf("id = %d nd0 = %d, nd1 = %d, nd2 = %d\n", i, point[0], point[1], point[2]); + + segmentIndexList[i] = i; + + /* 10 / 01 / 00 */ + alpha[0] = 1.0; alpha[1] = 0.0; + AmiraCallPositionParametrization(i, alpha, pos); + for(j=0; j<DIM; j++) + coordinates[0][j] = pos[j]; + + alpha[0] = 0.0; alpha[1] = 1.0; + AmiraCallPositionParametrization(i, alpha, pos); + for(j=0; j<DIM; j++) + coordinates[1][j] = pos[j]; + + alpha[0] = 0.0; alpha[1] = 0.0; + AmiraCallPositionParametrization(i, alpha, pos); + for(j=0; j<DIM; j++) + coordinates[2][j] = pos[j]; + + + /* map Amira Material ID's to UG material ID's */ + + left++; + right++; + + alpha[0] = alpha[1] = 0; + beta[0] = beta[1] = 1; + + if (UG3d::CreateBoundarySegment(segmentName, + left, /*id of left subdomain */ + right, /*id of right subdomain*/ + i, /*id of segment*/ + 3, // it' a triangle + 1, // resolution, whatever that is + point, + alpha, beta, + SegmentDescriptionByAmira, + (void *) (segmentIndexList+i) + )==NULL) + return(1); + + /* sprintf(BndCondName, "BndCond of Segment %d", i); */ + /* if(CreateBoundaryCondition(BndCondName, i,DummyBndCondition, NULL) == NULL) */ + /* return(1); */ + + } + + printf("%d segments created!\n", noOfSegments); + + /* That's it!*/ + return(0); + + +} + + +int ListEnvCommand (int argc, char **argv); + +/** \todo Clear grid before reading! */ +//template<> +void Dune::AmiraMeshReader<Dune::UGGrid<3,3>, double>::read(Dune::UGGrid<3,3>& grid, + const std::string& filename) try +{ + printf("This is the AmiraMesh reader for UGGrid<3,3>!\n"); + + //loaddomain $file @PARA_FILE $name @DOMAIN + CreateDomain(grid, "olisDomain", "cube.par.am"); + + //configure @PROBLEM $d @DOMAIN; + char* configureArgs[2] = {"configure DuneDummyProblem", "d olisDomain"}; + UG3d::ConfigureCommand(2, configureArgs); + + + printf("new DuneMG $b DuneDummyProblem $f DuneFormat $h 1G\n"); + //new @PROBLEM $b @PROBLEM $f @FORMAT $h @HEAP; + char* newArgs[4] = {"new DuneMG", "b DuneDummyProblem", "f DuneFormat", "h 1G"}; + if (UG3d::NewCommand(4, newArgs)) + assert(false); + + + // //////////////////////////////////////////// + // loadmesh $file @GRID_FILE $name @DOMAIN; + + const int DIM = 3; + + int i; + double nodePos[DIM]; +#if 0 + char DomainName[NAMESIZE]; + char filename[NAMESIZE]; + INT maxBndNodeID, noOfInnerNodes, noOfBndNodes, + noOfElem, noOfCreatedElem, nMapNodes, created; +#endif + UG3d::NODE* theNode; + + printf("Loading Amira mesh %s\n", filename.c_str()); + + // ///////////////////////////////////////////////////// + // Load the AmiraMesh file + AmiraMesh* am = AmiraMesh::read(filename.c_str()); + + if(!am) + throw("Could not open AmiraMesh file"); + + float* am_node_coordinates_float = NULL; + double* am_node_coordinates_double = NULL; + + // get the different data fields + AmiraMesh::Data* am_coordinateData = am->findData("Nodes", HxFLOAT, 3, "Coordinates"); + if (am_coordinateData) + am_node_coordinates_float = (float*) am_coordinateData->dataPtr(); + else { + am_coordinateData = am->findData("Nodes", HxDOUBLE, 3, "Coordinates"); + if (am_coordinateData) + am_node_coordinates_double = (double*) am_coordinateData->dataPtr(); + else + throw("No vertex coordinates found in the file!"); + + } + + + AmiraMesh::Data* tetrahedronData = am->findData("Tetrahedra", HxINT32, 4, "Nodes"); + int* elemData = (int*)tetrahedronData->dataPtr(); + + /* + All Boundary nodes are assumed to be inserted already. + We just have to insert the inner nodes and the elements + */ + UG3d::multigrid* theMG = UG3d::GetMultigrid("DuneMG"); + assert(theMG); + + int maxBndNodeID = -1; + for (theNode=theMG->grids[0]->firstNode[0]; theNode!=NULL; theNode=theNode->succ) + { + // The following two lines ought to be in here, but the + // OBJT macros is somewhat complicated, so I leave it out + // for the time being. + // if(OBJT(theNode->myvertex) == UG3d::IVOBJ) + // UserWriteF("Warning: Node %d is inner node\n", ID(theNode)); + maxBndNodeID = MAX(theNode->id, maxBndNodeID); + } + UG3d::UserWriteF("Already %d nodes existing\n", maxBndNodeID+1); + + + //noOfBndNodes = maxBndNodeID; + + + int noOfNodes = am->nElements("Nodes"); + + // noOfInnerNodes = noOfNodes - noOfBndNodes; + printf("AmiraMesh has %d total nodes\n", noOfNodes); + + + + + + for(i = 0; i < noOfNodes; i++) { + + assert(am_node_coordinates_float || am_node_coordinates_double); + if (am_node_coordinates_float) { + nodePos[0] = am_node_coordinates_float[3*i]; + nodePos[1] = am_node_coordinates_float[3*i+1]; + nodePos[2] = am_node_coordinates_float[3*i+2]; + } else { + nodePos[0] = am_node_coordinates_double[3*i]; + nodePos[1] = am_node_coordinates_double[3*i+1]; + nodePos[2] = am_node_coordinates_double[3*i+2]; + } + + /// \todo Warum ist nicht UG3d::InsertInnerNode Pflicht??? + if (InsertInnerNode(theMG->grids[0], nodePos) == NULL) + throw("inserting an inner node failed"); + + } + + + + /* all inner nodes are inserted , now we insert the elements */ + int noOfElem = am->nElements("Tetrahedra");; + + int noOfCreatedElem = 0; + for(i=0; i < noOfElem; i++) + { + int cornerIDs[4], j; + + //AmiraGetCornerIDsOfElem(i, cornerIDs); + + /* only tetrahedrons */ + /* printf("MeshAccess: elem id : %d, node ids : %d %d %d %d\n", i, + elemData[4*i+0], elemData[4*i+1], elemData[4*i+2], elemData[4*i+3]);*/ + cornerIDs[0] = elemData[4*i]-1; + cornerIDs[1] = elemData[4*i+1]-1; + cornerIDs[2] = elemData[4*i+2]-1; + cornerIDs[3] = elemData[4*i+3]-1; + + + /* printf("elem id : %d, node ids : %d %d %d %d\n", i, cornerIDs[0], cornerIDs[1], cornerIDs[2], cornerIDs[3]); */ + + if (InsertElementFromIDs(theMG->grids[0], 4,cornerIDs, NULL) == NULL) + throw("inserting an element failed"); + + noOfCreatedElem++; + // if(statusBar) + // if(i % 150 == 0) + // printf("Already %d of %d elements created: %2.1f %%\r",i,noOfElem, + // 100. * (DOUBLE) i / ((DOUBLE)(noOfElem))); + + } + + // if(statusBar) { + // UserWriteF("Finished: %d of %d elements created: %2.1f %%\n",i,noOfElem, + // 100. * (DOUBLE) i / ((DOUBLE)(noOfElem))); + // printf("\n"); + // } + + + if(noOfElem != noOfCreatedElem) + throw("inserting an element failed"); + + UG3d::UserWriteF("amiraloadmesh: %d elements created\n", noOfCreatedElem); + + // set the subdomainIDs + AmiraMesh::Data* am_material_ids = am->findData("Tetrahedra", HxBYTE, 1, "Materials"); + if (!am_material_ids) + throw("Field 'Materials' not found."); + + char* material_ids = (char*)am_material_ids->dataPtr(); + + i = 0; + UG3d::ELEMENT* theElement; + for (theElement=theMG->grids[0]->elements[0]; theElement!=NULL; theElement=theElement->ge.succ) + { + + /* get subdomain of element */ + int id = material_ids[i]; + + /** \todo These macros need to go, of course */ +#define ControlWord(p,ce) (((unsigned int *)(p))[UG3d::control_entries[ce].offset_in_object]) + +#define CW_WRITE(p, ce, n) ControlWord(p,ce) = (ControlWord(p,ce)&UG3d::control_entries[ce].xor_mask)|(((n)<<UG3d::control_entries[ce].offset_in_word)&UG3d::control_entries[ce].mask) + +#define SETSUBDOMAIN(p,n) CW_WRITE(p,UG3d::SUBDOMAIN_CE,n) + + SETSUBDOMAIN(theElement, id+1); + + //printf("element: %d, id: %d\n", i, id+1); + + i++; + } + + delete am; + + + + // if (MG_COARSE_FIXED(theMG)) + // return (GM_OK); + UG3d::SetEdgeAndNodeSubdomainFromElements(theMG->grids[0]); + + + /** \todo Do we really need to call CreateAlgebra for Dune?*/ + // if (UG3d::CreateAlgebra(theMG) != GM_OK) + // REP_ERR_RETURN (GM_ERROR); + + /** \todo Check whether this release is necessary */ + /* here all temp memory since CreateMultiGrid is released */ + //UG3d::ReleaseTmpMem(MGHEAP(theMG),MG_MARK_KEY(theMG)); +#define FROM_TOP 1 +#define ReleaseTmpMem(p,k) Release(p,FROM_TOP,k) + ReleaseTmpMem(theMG->theHeap, theMG->MarkKey); + theMG->MarkKey = 0; + + UG3d::UserWriteF("Coarse grid fixed. Do not call fixcoarsegrid.\n"); + + + return; + + +} +catch (const char* msg) { + + printf("%s\n", msg); + return; +} diff --git a/lib/io/amuggridwriter.cc b/lib/io/amuggridwriter.cc new file mode 100644 index 000000000..bd6e4d50d --- /dev/null +++ b/lib/io/amuggridwriter.cc @@ -0,0 +1,316 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +// /////////////////////////////////////////////// +// Specialization of the AmiraMesh writer for SimpleGrid<3,3> +// /////////////////////////////////////////////// + +#include "../../grid/uggrid.hh" + +#include <amiramesh/AmiraMesh.h> + +namespace Dune { + + template<> + class AmiraMeshWriter<UGGrid<3,3>, double> { + + public: + + static void write(const UGGrid<3,3>& grid, + const Array<double>& sol, + const std::string& filename); + + + AmiraMeshWriter() {} + + }; + +} + +//template<> +void Dune::AmiraMeshWriter<Dune::UGGrid<3,3>, double>::write(const Dune::UGGrid<3,3>& grid, + const Array<double>& sol, + const std::string& filename) +{ + printf("This is the AmiraMesh writer for UGGrid<3,3>!\n"); + + const int DIM = 3; + + int noOfNodes = 0; //grid.size(0, 3); + + printf("Ă„hem\n"); + int fl, tl, k, i, noOfElem, noOfBndTri, MarkKey, ncomp, maxSubDom; + //UG3d::VECDATA_DESC *sol = NULL; + UG3d::ELEMENT *t, **elemList; + UG3d::VECTOR *vec; + UG3d::NODE* theNode; + std::string solFilename; + + + fl = 0; + // tl = TOPLEVEL(theMG); + + // Construct the name for the geometry file + std::string geoFilename(filename); + geoFilename += ".am"; + +#if 0 + /* reset vcflag */ + for (k=fl; k<=tl; k++) + for (vec=PFIRSTVECTOR(GRID_ON_LEVEL(theMG,k)); vec!= NULL; vec=SUCCVC(vec)) + SETVCFLAG(vec, 0); + + + /*count nodes and enumerate nodes */ + noOfNodes = 0; + for (k=fl; k<=tl; k++) + for (t=FIRSTELEMENT(GRID_ON_LEVEL(theMG,k)); t!=NULL; t=SUCCE(t)) + if(AmiraElement(t, tl, k)) + if(EnumerateAmiraNodes(t, sol, &noOfNodes)) + return(PARAMERRORCODE); +#endif + +#if 0 + /* build up list of all surface elements and count nodes */ + noOfElem = 0; + maxSubDom = 0; + for (k=fl; k<=tl; k++) + for (t=FIRSTELEMENT(GRID_ON_LEVEL(theMG,k)); t!=NULL; t=SUCCE(t)) + if(AmiraElement(t, tl, k)) + { + noOfElem++; + maxSubDom = MAX(maxSubDom, SUBDOMAIN(t)); + } + + MarkTmpMem(MGHEAP(theMG), &MarkKey); + elemList = (ELEMENT **) GetTmpMem(MGHEAP(theMG), (noOfElem+1)*sizeof(ELEMENT *), MarkKey); + if(elemList == NULL) + return(1); + + + i = noOfNodes; + noOfNodes = 0; + for (k=fl; k<=tl; k++) + for (vec=PFIRSTVECTOR(GRID_ON_LEVEL(theMG,k)); vec!= NULL; vec=SUCCVC(vec)) + { + + if(!VCFLAG(vec)) + continue; + VINDEX(vec) = ++noOfNodes; + if(VOTYPE(vec) != NODEVEC) + { + PrintErrorMessage('E',"WriteAmiraGeometry","vector not of type NODEVEC"); + return (PARAMERRORCODE); + } + } + + if(FULLREFINELEVEL(theMG) < TOPLEVEL(theMG)) + for (k = tl; k >= MAX(fl, BOTTOMLEVEL(theMG)+1); k--) + for (theNode=FIRSTNODE(GRID_ON_LEVEL(theMG,k)); theNode!=NULL; theNode=SUCCN(theNode)) + { + NODE* fatherNode; + VECTOR *fatherVec; + + vec = NVECTOR(theNode); + + if(vec == NULL) + continue; + + if(!CORNERTYPE(theNode)) + continue; + + fatherNode = (NODE*) NFATHER(theNode); + + if(fatherNode == NULL) + continue; + + fatherVec = (VECTOR*) NVECTOR(fatherNode); + + if(fatherVec == NULL) + { + PrintErrorMessage('E',"WriteAmiraGeometry","father node without vector"); + return (PARAMERRORCODE); + } + if(VCFLAG(fatherVec)) + { + PrintErrorMessage('E',"WriteAmiraGeometry","father vec with VCFLAG"); + return (PARAMERRORCODE); + } + VINDEX(fatherVec) = VINDEX(vec); + } + + if(i != noOfNodes) + PrintErrorMessage('E',"WriteAmira","wrong number of nodes"); + + assert(i == noOfNodes); + /* write elemts to list */ + + noOfElem = 0; + noOfBndTri = 0; + for (k=fl; k<=tl; k++) + for (t=FIRSTELEMENT(GRID_ON_LEVEL(theMG,k)); t!=NULL; t=SUCCE(t)) + if (AmiraElement(t, tl, k)) + { + elemList[noOfElem++] = t; +#ifndef ModelP + if (OBJT(t) != BEOBJ) + continue; +#endif + for (i=0; i<SIDES_OF_ELEM(t); i++) + if (ElemSideOnPlotBnd(t, i, NULL) > 0) + noOfBndTri++; + } +#endif + + + // create amiramesh object + AmiraMesh am_geometry; + + // 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); + + + // i=0; + // for (k=fl; k<=tl; k++) + // for (vec=FIRSTVECTOR(GRID_ON_LEVEL(theMG,k)); vec!= NULL; vec=SUCCVC(vec)) + // if ((VOTYPE(vec) == NODEVEC) && ((k==tl) || (VNCLASS(vec)<1) )) + // { + // /* write coordinates to geo file */ + // DOUBLE pos[DIM]; + + // if(VectorPosition(vec, pos)) + // return(PARAMERRORCODE); + + // ((float*)geo_node_data->dataPtr())[i++] = pos[0]; + // ((float*)geo_node_data->dataPtr())[i++] = pos[1]; + // ((float*)geo_node_data->dataPtr())[i++] = pos[2]; + + // } + + UGGridLevelIterator<3, 3, 3> vertex = grid.lbegin<3>(0); + printf("level: %d\n", vertex.level()); + + + + UGGridLevelIterator<0, 3, 3> element = grid.lbegin<0>(0); + + for (i=0; element!=grid.lend<0>(0); element++, i++) + printf("Element! %d\n", i); + +#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)); + + + /* write element section to geo - file */ + AmiraMesh::Location* element_loc = new AmiraMesh::Location("Tetrahedra", noOfElem); + am_geometry.insert(element_loc); + + AmiraMesh::Data* element_data = new AmiraMesh::Data("Nodes", element_loc, + McPrimType::mc_int32, DIM+1); + am_geometry.insert(element_data); + + int (*dPtr)[DIM+1] = (int(*)[DIM+1])element_data->dataPtr(); + + for(i=0; i<noOfElem; i++) + if(WriteAmiraGeometry(dPtr[i], elemList[i], sol)) + return(PARAMERRORCODE); + + // 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]); + + // fprintf(geoFile, "\n@%d\n", 4 /* BND_TRIDATA_SECTION */); + // for(i=0;i<noOfElem;i++) + // if(WriteAmiraBndTriData(geoFile, elemList[i], ncomp)) + // return(PARAMERRORCODE); + + // fprintf(geoFile, "\n@%d\n", 5 /* BND_TRI_SECTION */); + // for(i=0;i<noOfElem;i++) + // if(WriteAmiraBndTri(geoFile, elemList[i])) + // return(PARAMERRORCODE); + + + + + ////////////////////////////////////////////////////// + + // Now save the solution + // Construct the name for the solution file + + //strcpy(solFilename, (const char*) BaseName); +#ifdef ModelP + //strcat(solFilename, procNumber); +#endif + //strcat(solFilename, ".sol"); + + //AmiraMesh am_solution; + + //AmiraMesh::Location* nodes = new AmiraMesh::Location("Nodes", noOfNodes); + //am_solution.insert(nodes); + + AmiraMesh::Data* nodeData = new AmiraMesh::Data("Data", geo_nodes, McPrimType::mc_float, ncomp); + am_geometry.insert(nodeData); + + AmiraMesh::Field* nodeField = new AmiraMesh::Field("f", ncomp, McPrimType::mc_float, + AmiraMesh::t_linear, nodeData); + am_geometry.insert(nodeField); + + i=0; + for (k=fl; k<=tl; k++) + for (vec=FIRSTVECTOR(GRID_ON_LEVEL(theMG,k)); vec!= NULL; vec=SUCCVC(vec)) + if ((VOTYPE(vec) == NODEVEC) && ((k==tl) || (VNCLASS(vec)<1) )) + { + SHORT vtype = VTYPE(vec); + /** \bug This definition of ncomp shadows another one! */ + SHORT ncomp = VD_NCMPS_IN_TYPE(sol, vtype); + SHORT *cmpptr = VD_CMPPTR_OF_TYPE(sol, vtype); + SHORT j; + + for (j=0; j<ncomp; j++) + ((float*)nodeData->dataPtr())[ncomp*i+j] = VVALUE(vec, cmpptr[j]); + + i++; + } + + // actually save the solution file + // if (!am_solution.write(solFilename, 1) ) { + // printf("An error has occured writing file %s.\n", solFilename); + // return PARAMERRORCODE; + // } + +#endif + if(!am_geometry.write(geoFilename.c_str(), 1)) { + printf("writing geometry file failed in amira : \n"); + /** \todo Do a decent error handling */ + return; + } + + printf("Grid written successfully to:\n %s \n", geoFilename.c_str()); +} -- GitLab