diff --git a/CMakeLists.txt b/CMakeLists.txt index a66fc0842ece9ecad85e305eaff2931809db1e40..e41c62e4db08969110703a76506c16b036ffe5fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ ADD_SUBDIRECTORY( GeoLib ) ADD_SUBDIRECTORY( MathLib ) ADD_SUBDIRECTORY( MeshLib ) ADD_SUBDIRECTORY( SimpleTests/MatrixTests ) +ADD_SUBDIRECTORY( SimpleTests/MeshTests ) IF(NOT MSVC) ADD_SUBDIRECTORY( SimpleTests/SolverTests ) ENDIF(NOT MSVC) diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fe8840c4524de4acb7371570417c0a878dd7cdbd --- /dev/null +++ b/FileIO/CMakeLists.txt @@ -0,0 +1,20 @@ +# Source files +GET_SOURCE_FILES(SOURCES_FILEIO) +SET ( SOURCES ${SOURCES_FILEIO}) + +# Create the library +ADD_LIBRARY(FileIO STATIC ${SOURCES}) + +include_directories( + . + ../Base + ../GeoLib + ../MathLib + ../MeshLib +) + +target_link_libraries (FileIO + GeoLib + MeshLib +) + diff --git a/FileIO/MeshIO.cpp b/FileIO/MeshIO.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2444bae5a56ad1d4b80c241898cdd5e83e2ed105 --- /dev/null +++ b/FileIO/MeshIO.cpp @@ -0,0 +1,215 @@ +/** + * MeshIO.cpp + * + * Date: 2012/05/08 + * Author: KR + */ + +#include "GEOObjects.h" +#include "MeshIO.h" +#include "Node.h" +#include "Elements/Edge.h" +#include "Elements/Tri.h" +#include "Elements/Quad.h" +#include "Elements/Tet.h" +#include "Elements/Hex.h" +#include "Elements/Pyramid.h" +#include "Elements/Prism.h" + +#include <iomanip> +#include <sstream> + +namespace FileIO +{ + +MeshIO::MeshIO() +: _mesh(NULL) +{ +} + +MeshLib::Mesh* MeshIO::loadMeshFromFile(const std::string& file_name) +{ + std::cout << "Read mesh ... " << std::endl; +/* + #ifndef NDEBUG + QTime myTimer; + myTimer.start(); + #endif + */ + std::ifstream in (file_name.c_str(),std::ios::in); + if (!in.is_open()) + { + std::cout << "CFEMesh::FEMRead() - Could not open file...\n"; + return NULL; + } + + std::string line_string (""); + getline(in, line_string); + + std::vector<MeshLib::Node*> nodes; + std::vector<MeshLib::Element*> elements; + + if(line_string.find("#FEM_MSH") != std::string::npos) // OGS mesh file + { + while (!in.eof()) + { + getline(in, line_string); + + // check keywords + if (line_string.find("#STOP") != std::string::npos) + break; + else if (line_string.find("$NODES") != std::string::npos) + { + double x, y, z, double_dummy; + unsigned nNodes, idx; + in >> nNodes >> std::ws; + std::string s; + std::ios::pos_type position = in.tellg(); + for (unsigned i = 0; i < nNodes; i++) + { + in >> idx >> x >> y >> z; + MeshLib::Node* node(new MeshLib::Node(x, y, z, nodes.size())); + nodes.push_back(node); + position = in.tellg(); + in >> s; + if (s.find("$AREA") != std::string::npos) + in >> double_dummy; + else + in.seekg(position, std::ios::beg); + in >> std::ws; + } + } + else if (line_string.find("$ELEMENTS") != std::string::npos) + { + unsigned nElements; + in >> nElements >> std::ws; + for (unsigned i = 0; i < nElements; i++) + { + getline(in, line_string); + + elements.push_back(readElement(line_string, nodes)); + } + } + } + + MeshLib::Mesh* mesh (new MeshLib::Mesh(file_name, nodes, elements)); + std::cout << "Nr. Nodes: " << nodes.size() << std::endl; + std::cout << "Nr. Elements: " << elements.size() << std::endl; + + /* + #ifndef NDEBUG + std::cout << "Loading time: " << myTimer.elapsed() << " ms" << std::endl; + #endif + */ + return mesh; + } + else + { + in.close(); + return NULL; + } +} + +MeshLib::Element* MeshIO::readElement(const std::string& line, const std::vector<MeshLib::Node*> &nodes) +{ + std::stringstream ss (line); + std::string elem_type_str; + unsigned index, patch_index; + ss >> index >> patch_index >> elem_type_str; + + MshElemType::type elem_type (String2MshElemType(elem_type_str)); + unsigned* idx = new unsigned[8]; + + MeshLib::Element* elem; + + switch(elem_type) + { + case MshElemType::LINE: + for (int i = 0; i < 2; i++) + ss >> idx[i]; + elem = new MeshLib::Edge(nodes[idx[0]], nodes[idx[1]], patch_index); + break; + case MshElemType::TRIANGLE: + for (int i = 0; i < 3; i++) + ss >> idx[i]; + elem = new MeshLib::Tri(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], patch_index); + break; + case MshElemType::QUAD: + for (int i = 0; i < 4; i++) + ss >> idx[i]; + elem = new MeshLib::Quad(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], patch_index); + break; + case MshElemType::TETRAHEDRON: + for (int i = 0; i < 4; i++) + ss >> idx[i]; + elem = new MeshLib::Tet(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], patch_index); + break; + case MshElemType::HEXAHEDRON: + for (int i = 0; i < 8; i++) + ss >> idx[i]; + elem = new MeshLib::Hex(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], nodes[idx[5]], nodes[idx[6]], nodes[idx[7]], patch_index); + break; + case MshElemType::PYRAMID: + for (int i = 0; i < 5; i++) + ss >> idx[i]; + elem = new MeshLib::Pyramid(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], patch_index); + break; + case MshElemType::PRISM: + for (int i = 0; i < 6; i++) + ss >> idx[i]; + elem = new MeshLib::Prism(nodes[idx[0]], nodes[idx[1]], nodes[idx[2]], nodes[idx[3]], nodes[idx[4]], nodes[idx[5]], patch_index); + break; + default: + elem = NULL; + } + + /* + neighbors.resize(nfaces); + for (unsigned i = 0; i < nfaces; i++) + neighbors[i] = NULL; + */ + + return elem; +} + +int MeshIO::write(std::ostream &out) +{ + /* + if(!_mesh) + { + std::cout << "OGSMeshIO cannot write: no mesh set!" << std::endl; + return 0; + } + + setPrecision(9); + + out << "#FEM_MSH" << std::endl; + + out << "$PCS_TYPE" << std::endl << " " << _mesh->pcs_name << std::endl; + + out << "$NODES" << std::endl << " "; + const size_t n_nodes(_mesh->GetNodesNumber(false)); + out << n_nodes << std::endl; + for (size_t i(0); i < n_nodes; i++) + { + double const* const coords (_mesh->nod_vector[i]->getData()); + out << i << " " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; + } + + out << "$ELEMENTS" << std::endl << " "; + writeElementsExceptLines(_mesh->ele_vector, out); + + out << " $LAYER" << std::endl; + out << " "; + out << _mesh->_n_msh_layer << std::endl; + out << "#STOP" << std::endl; + */ + return 1; +} + +void MeshIO::setMesh(const MeshLib::Mesh* mesh) +{ + _mesh = mesh; +} + +} // end namespace FileIO diff --git a/FileIO/MeshIO.h b/FileIO/MeshIO.h new file mode 100644 index 0000000000000000000000000000000000000000..2a935dcee0753b6fa47e0104abdb7d8b3b5ed6d6 --- /dev/null +++ b/FileIO/MeshIO.h @@ -0,0 +1,58 @@ +/** + * MeshIO.h + * + * Date: 2012/05/08 + * Author: KR + */ + +/** + * This is currently just test functionality for testing ogs-6 mesh data structures! + */ + +#ifndef MESHIO_H_ +#define MESHIO_H_ + +#include "Writer.h" + +#include <sstream> +#include <iostream> +#include <vector> + +namespace MeshLib +{ + class Mesh; + class Node; + class Element; +} + +namespace FileIO +{ +class MeshIO : public Writer +{ +public: + /// Constructor. + MeshIO(); + + virtual ~MeshIO() {}; + + /// Read mesh from file. + MeshLib::Mesh* loadMeshFromFile(const std::string& fileName); + + /// Set mesh for writing. + void setMesh(const MeshLib::Mesh* mesh); + +protected: + /// Write mesh to stream. + int write(std::ostream &out); + +private: + MeshLib::Element* readElement(const std::string& line, const std::vector<MeshLib::Node*> &nodes); + + const MeshLib::Mesh* _mesh; + +}; /* class */ + +} /* namespace */ + +#endif /* MESHIO_H_ */ + diff --git a/FileIO/Writer.cpp b/FileIO/Writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06f6c8f1429fe9f0c5ada3ec89d06a9a86229b69 --- /dev/null +++ b/FileIO/Writer.cpp @@ -0,0 +1,65 @@ +/** + * \file Writer.cpp + * 13/02/2012 LB Initial implementation + * + * Implementation of the Writer class + */ + +// ** INCLUDES ** +#include "Writer.h" + +#include <fstream> + +namespace FileIO +{ + +Writer::Writer() +{ +} + +std::string Writer::writeToString() +{ + // Empty stream and clear error states. + _out.str(""); + _out.clear(); + + if (this->write(_out)) + return _out.str(); + else + return std::string(""); +} + +int Writer::writeToFile(std::string const& filename) +{ + std::string file_content = this->writeToString(); + if (!file_content.empty()) + { + std::ofstream fileStream; + fileStream.open (filename.c_str()); + + // check file stream + if (!fileStream) + { + std::cerr << "Could not open file " << filename << " !" << std::endl; + return 0; + } + + fileStream << file_content; + + fileStream.close(); + return 1; + } + return 0; +} + +void Writer::setPrecision(unsigned int precision) +{ + _out.precision(precision); +} + +void Writer::setFormat(std::ios_base::fmtflags flags) +{ + _out.setf(flags); +} + +} // namespace FileIO diff --git a/FileIO/Writer.h b/FileIO/Writer.h new file mode 100644 index 0000000000000000000000000000000000000000..f02dec1591fc9af7fabb3c967898f2bd14c770e5 --- /dev/null +++ b/FileIO/Writer.h @@ -0,0 +1,53 @@ +/** + * \file Writer.h + * 13/02/2012 LB Initial implementation + */ + +#ifndef WRITER_H +#define WRITER_H + +#include <string> +#include <iostream> +#include <sstream> + +namespace FileIO +{ + +/// @brief Base class which enables writing an object to string, stringstream +/// or file. Also formatting (precision, scientific notation of decimal values) +/// can be set. +/// +/// When subclassing you only need to implement void write(std::ostream& stream). +class Writer +{ +public: + Writer(); + virtual ~Writer() {}; + + /// @brief Writes the object to a string. + std::string writeToString(); + + /// @brief Writes the object to the given file. + int writeToFile(std::string const& filename); + + /// @brief Sets the decimal precision. + void setPrecision(unsigned int precision); + + /// @brief Sets the format (either ios::scientific or ios::fixed); + void setFormat(std::ios_base::fmtflags flags); + +protected: + /// @brief Writes the object to the given stream. + /// This method must be implemented by a subclass. + virtual int write(std::ostream& stream) = 0; + + /// @brief The stream to write to. + std::stringstream _out; + +private: + +}; + +} // namespace FileIO + +#endif // WRITER_H diff --git a/MathLib/MathTools.cpp b/MathLib/MathTools.cpp index d683e1284bd21f6464f05ca0c306367d65a6b6d4..88cebe7fae95aa091a8bab3dde0902433c6840fb 100644 --- a/MathLib/MathTools.cpp +++ b/MathLib/MathTools.cpp @@ -86,7 +86,7 @@ double getAngle (const double p0[3], const double p1[3], const double p2[3]) return acos (scpr (v0,v1,3) / (sqrt(scpr(v0,v0,3)) * sqrt(scpr (v1,v1,3)))); } -double calcTriangleaArea(const double p0[3], const double p1[3], const double p2[3]) +double calcTriangleArea(const double* p0, const double* p1, const double* p2) { const double u0 (p2[0] - p0[0]); const double u1 (p2[1] - p0[1]); diff --git a/MathLib/MathTools.h b/MathLib/MathTools.h index 5200b78726a0d4cd5f9a0236e13c5c050a12cc64..344d4308009bfed12c830161ad7352e5ccb109b2 100644 --- a/MathLib/MathTools.h +++ b/MathLib/MathTools.h @@ -98,7 +98,7 @@ double getAngle (const double p0[3], const double p1[3], const double p2[3]); * Calculates the area of a triangle. * The formula is A=.5*|u x v|, i.e. half of the area of the parallelogram specified by u=p0->p1 and v=p0->p2. */ -double calcTriangleArea(const double p0[3], const double p1[3], const double p2[3]); +double calcTriangleArea(const double* p0, const double* p1, const double* p2); /** * Calculates the volume of a tetrahedron. diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h index 3e07b798d0cc0e5fa8f4b6cd3498fc8151aca971..af765dfd52e694304c0e1854da89ed87774a7dec 100644 --- a/MeshLib/Elements/Element.h +++ b/MeshLib/Elements/Element.h @@ -22,8 +22,8 @@ class Node; class Element { /* friend functions: */ - friend void Mesh::setElementInformationForNodes(); - friend void Mesh::addElement(Element*); + friend class Mesh;//void Mesh::setElementInformationForNodes(); + //friend void Mesh::addElement(Element*); public: diff --git a/MeshLib/FemMesh.cpp b/MeshLib/FemMesh.cpp index fa4b55d1464aa4f805e9026b5a5d4f2dd107d71e..57139554a5c88ee42c7afd2e8fa3a87573de2b0d 100644 --- a/MeshLib/FemMesh.cpp +++ b/MeshLib/FemMesh.cpp @@ -24,11 +24,6 @@ FemMesh::FemMesh(const FemMesh &mesh) { } -FemMesh::FemMesh(const std::string &file_name) - : Mesh(file_name) -{ -} - FemMesh::~FemMesh() { diff --git a/MeshLib/FemMesh.h b/MeshLib/FemMesh.h index 335ca5187896b765edc63fb1a78a40257009dd4a..9a390cd4e6cbb849b5cb3a4a2e161e56ecd3e0b3 100644 --- a/MeshLib/FemMesh.h +++ b/MeshLib/FemMesh.h @@ -27,9 +27,6 @@ public: /// Copy constructor FemMesh(const FemMesh &mesh); - /// Constructor for reading a mesh from a file - FemMesh(const std::string &file_name); - /// Destructor virtual ~FemMesh(); diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp index fed2318fdf932d4b213a7c0043890bf5446d2879..d9784233051932604cf09d40dfab774525800b22 100644 --- a/MeshLib/Mesh.cpp +++ b/MeshLib/Mesh.cpp @@ -30,12 +30,6 @@ Mesh::Mesh(const Mesh &mesh) { } -Mesh::Mesh(const std::string &file_name) -{ - // read mesh - this->makeNodesUnique(); -} - Mesh::~Mesh() { const size_t nElements (_elements.size()); diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h index 8f71750c76638f47bce2f63ee3292bc39e9f67de..abdfbe036b92c1ab5cdd21fdd881fe8d2ff0b321 100644 --- a/MeshLib/Mesh.h +++ b/MeshLib/Mesh.h @@ -31,9 +31,6 @@ public: /// Copy constructor Mesh(const Mesh &mesh); - /// Constructor for reading a mesh from a file - Mesh(const std::string &file_name); - /// Destructor virtual ~Mesh(); diff --git a/MeshLib/Node.h b/MeshLib/Node.h index f2bcec99569f9c835f16fd50018da59d0a9e832c..c92ba2c507c682338e3e257e93509a8e806da735 100644 --- a/MeshLib/Node.h +++ b/MeshLib/Node.h @@ -25,8 +25,8 @@ class Element; class Node : public GEOLIB::PointWithID { /* friend functions: */ - friend void Mesh::setElementInformationForNodes(); - friend void Mesh::addElement(Element*); + friend class Mesh;//void Mesh::setElementInformationForNodes(); + //friend void Mesh::addElement(Element*); public: diff --git a/SimpleTests/MeshTests/CMakeLists.txt b/SimpleTests/MeshTests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a52b603aa694b327a7fffc51466a319ac1b9da1 --- /dev/null +++ b/SimpleTests/MeshTests/CMakeLists.txt @@ -0,0 +1,25 @@ + +INCLUDE_DIRECTORIES( + . + ${CMAKE_SOURCE_DIR}/Base/ + ${CMAKE_SOURCE_DIR}/Base/logog/include + ${CMAKE_SOURCE_DIR}/FileIO/ + ${CMAKE_SOURCE_DIR}/MathLib/ + ${CMAKE_SOURCE_DIR}/MeshLib/ +) + +# Create the executable +ADD_EXECUTABLE( MeshRead + MeshRead.cpp + ${SOURCES} + ${HEADERS} +) + +TARGET_LINK_LIBRARIES ( MeshRead + MeshLib + FileIO + MathLib + Base + GeoLib +) + diff --git a/SimpleTests/MeshTests/MeshRead.cpp b/SimpleTests/MeshTests/MeshRead.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6cfd71c00d0abf4b61218612390320feecabb7ac --- /dev/null +++ b/SimpleTests/MeshTests/MeshRead.cpp @@ -0,0 +1,19 @@ +/* + * MeshRead.cpp + * + * Created on: 2012/05/09 + * Author: KR + */ + +#include "Mesh.h" +#include "MeshIO.h" + +int main(int argc, char *argv[]) +{ + std::string file_name("c:/Project/Data/Ammer/Ammer-Homogen100m-Final.msh"); + FileIO::MeshIO mesh_io; + MeshLib::Mesh* mesh = mesh_io.loadMeshFromFile(file_name); + + delete mesh; +} +