diff --git a/MeshLib/MeshGenerators/MeshGenerator.cpp b/MeshLib/MeshGenerators/MeshGenerator.cpp index cd6576856bab399266c7d8e1183e391d04aea06c..2f30171f6780cd9534df54e57aafd33bdef24598 100644 --- a/MeshLib/MeshGenerators/MeshGenerator.cpp +++ b/MeshLib/MeshGenerators/MeshGenerator.cpp @@ -18,6 +18,7 @@ #include "Elements/Line.h" #include "Elements/Quad.h" #include "Elements/Hex.h" +#include "Elements/Tri.h" #include <vector> @@ -174,4 +175,57 @@ Mesh* MeshGenerator::generateRegularHexMesh(const unsigned n_x_cells, return new Mesh(mesh_name, nodes, elements); } +Mesh* MeshGenerator::generateRegularTriMesh( + const double length, + const std::size_t subdivision, + const GeoLib::Point& origin) +{ + return generateRegularTriMesh(subdivision, subdivision, length/subdivision, origin); +} + +Mesh* MeshGenerator::generateRegularTriMesh(const unsigned n_x_cells, + const unsigned n_y_cells, + const double cell_size, + GeoLib::Point const& origin, + std::string const& mesh_name) +{ + //nodes + const unsigned n_x_nodes (n_x_cells+1); + const unsigned n_y_nodes (n_y_cells+1); + std::vector<Node*> nodes; + nodes.reserve(n_x_nodes * n_y_nodes); + + for (std::size_t i = 0; i < n_y_nodes; i++) + { + const double y_offset (origin[1] + cell_size * i); + for (std::size_t j = 0; j < n_x_nodes; j++) + nodes.push_back (new Node(origin[0] + cell_size * j, y_offset, origin[2])); + } + + //elements + std::vector<Element*> elements; + elements.reserve(n_x_cells * n_y_cells * 2); + + for (std::size_t j = 0; j < n_y_cells; j++) + { + const std::size_t offset_y1 = j * n_x_nodes; + const std::size_t offset_y2 = (j + 1) * n_x_nodes; + for (std::size_t k = 0; k < n_x_cells; k++) + { + std::array<Node*, 3> element1_nodes; + element1_nodes[0] = nodes[offset_y1 + k]; + element1_nodes[1] = nodes[offset_y2 + k + 1]; + element1_nodes[2] = nodes[offset_y2 + k]; + elements.push_back (new Tri(element1_nodes)); + std::array<Node*, 3> element2_nodes; + element2_nodes[0] = nodes[offset_y1 + k]; + element2_nodes[1] = nodes[offset_y1 + k + 1]; + element2_nodes[2] = nodes[offset_y2 + k + 1]; + elements.push_back (new Tri(element2_nodes)); + } + } + + return new Mesh(mesh_name, nodes, elements); +} + } diff --git a/MeshLib/MeshGenerators/MeshGenerator.h b/MeshLib/MeshGenerators/MeshGenerator.h index d9f72dc833e368023cdbbe5042c76fede33be0fb..11946d2711e80af1cc6a385e23cd573b43b384f2 100644 --- a/MeshLib/MeshGenerators/MeshGenerator.h +++ b/MeshLib/MeshGenerators/MeshGenerator.h @@ -103,6 +103,34 @@ Mesh* generateRegularHexMesh(const unsigned n_x_cells, GeoLib::Point const& origin = GeoLib::ORIGIN, std::string const& mesh_name = "mesh"); +/** + * Generate a regular 2D Triangle-Element mesh. The mesh is generated in the + * x-y-plane. + * + * \param length Mesh's dimensions in x- and y-directions. + * \param subdivision Number of subdivisions. + * \param origin Optional mesh's origin (the lower left corner) with GeoLib::ORIGIN default. + */ +Mesh* generateRegularTriMesh(const double length, + const std::size_t subdivision, + GeoLib::Point const& origin = GeoLib::ORIGIN); + +/** + * Generate a regular 2D Triangle-Element mesh. The mesh is generated in the + * x-y-plane. + * + * \param n_x_cells Number of cells in x-direction. + * \param n_y_cells Number of cells in y-direction. + * \param cell_size Edge length of two equal sides of isosceles triangles + * \param origin Optional mesh's origin (the lower left corner) with GeoLib::ORIGIN default. + * \param mesh_name Name of the new mesh. + */ +Mesh* generateRegularTriMesh(const unsigned n_x_cells, + const unsigned n_y_cells, + const double cell_size, + GeoLib::Point const& origin = GeoLib::ORIGIN, + std::string const& mesh_name = "mesh"); + } //MeshGenerator } //MeshLib diff --git a/Utils/SimpleMeshCreation/CMakeLists.txt b/Utils/SimpleMeshCreation/CMakeLists.txt index 3127d017eca514b5d221f67b41af38774d79d2ee..b2ec276f40c8c2ec5e872c9237d413843509a11d 100644 --- a/Utils/SimpleMeshCreation/CMakeLists.txt +++ b/Utils/SimpleMeshCreation/CMakeLists.txt @@ -1,15 +1,16 @@ -IF(TARGET VtkVis) - INCLUDE_DIRECTORIES( - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/BaseLib - ${CMAKE_SOURCE_DIR}/FileIO - ${CMAKE_SOURCE_DIR}/FileIO/Legacy - ${CMAKE_SOURCE_DIR}/GeoLib - ${CMAKE_SOURCE_DIR}/MathLib - ${CMAKE_SOURCE_DIR}/MeshLib - ${CMAKE_SOURCE_DIR}/Gui/VtkVis - ) +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/BaseLib + ${CMAKE_SOURCE_DIR}/FileIO + ${CMAKE_SOURCE_DIR}/FileIO/Legacy + ${CMAKE_SOURCE_DIR}/GeoLib + ${CMAKE_SOURCE_DIR}/MathLib + ${CMAKE_SOURCE_DIR}/MeshLib + ${CMAKE_SOURCE_DIR}/Gui/VtkVis +) + +IF(TARGET VtkVis) ADD_EXECUTABLE( generateStructuredQuadMesh generateStructuredQuadMesh.cpp ) SET_TARGET_PROPERTIES( generateStructuredQuadMesh PROPERTIES FOLDER Utils) @@ -35,3 +36,14 @@ IF(TARGET VtkVis) ) ENDIF() # VtkVis-target is existing + + +ADD_EXECUTABLE( generateStructuredMesh generateStructuredMesh.cpp ) +TARGET_LINK_LIBRARIES( generateStructuredMesh + BaseLib + FileIO + MathLib + MeshLib +) +SET_TARGET_PROPERTIES(generateStructuredMesh PROPERTIES FOLDER Utilities) + diff --git a/Utils/SimpleMeshCreation/generateStructuredMesh.cpp b/Utils/SimpleMeshCreation/generateStructuredMesh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f25e05b37c508991485d203c27384b5e6227f03f --- /dev/null +++ b/Utils/SimpleMeshCreation/generateStructuredMesh.cpp @@ -0,0 +1,97 @@ +/** + * @copyright + * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ + +// TCLAP +#include "tclap/CmdLine.h" + +// ThirdParty/logog +#include "logog/include/logog.hpp" + +// BaseLib +#include "LogogSimpleFormatter.h" + +// FileIO +#include "Legacy/MeshIO.h" + +// MeshLib +#include "Mesh.h" +#include "Node.h" +#include "Elements/Element.h" +#include "MeshEnums.h" +#include "MeshGenerators/MeshGenerator.h" + + +int main (int argc, char* argv[]) +{ + LOGOG_INITIALIZE(); + logog::Cout* logog_cout (new logog::Cout); + BaseLib::LogogSimpleFormatter *custom_format (new BaseLib::LogogSimpleFormatter); + logog_cout->SetFormatter(*custom_format); + + TCLAP::CmdLine cmd("Generate a structured mesh.", ' ', "0.1"); + TCLAP::ValueArg<std::string> mesh_out("o", "mesh-output-file", + "the name of the file the mesh will be written to", true, + "", "file name of output mesh"); + cmd.add(mesh_out); + TCLAP::ValueArg<std::string> eleTypeArg("e", "element-type", + "element type to be created", true, "line", "element type"); + cmd.add(eleTypeArg); + TCLAP::ValueArg<double> lengthArg("l", "length", + "length of a domain", true, 10.0, "length of a domain"); + cmd.add(lengthArg); + TCLAP::ValueArg<unsigned> nsubdivArg("n", "nr-subdivision", + "the number of subdivision", true, 10, "the number of subdivision"); + cmd.add(nsubdivArg); + + // parse arguments + cmd.parse(argc, argv); + const std::string eleTypeName(eleTypeArg.getValue()); + const MeshElemType eleType = String2MeshElemType(eleTypeName); + const double length = lengthArg.getValue(); + const unsigned n_subdivision = nsubdivArg.getValue(); + + // generate a mesh + MeshLib::Mesh* mesh = nullptr; + switch (eleType) + { + case MeshElemType::LINE: + mesh = MeshLib::MeshGenerator::generateLineMesh(length, n_subdivision); + break; + case MeshElemType::TRIANGLE: + mesh = MeshLib::MeshGenerator::generateRegularTriMesh(length, n_subdivision); + break; + case MeshElemType::QUAD: + mesh = MeshLib::MeshGenerator::generateRegularQuadMesh(length, n_subdivision); + break; + case MeshElemType::HEXAHEDRON: + mesh = MeshLib::MeshGenerator::generateRegularHexMesh(length, n_subdivision); + break; + default: + ERR("Given element type is not supported."); + break; + } + + if (mesh) + { + INFO("Mesh created: %d nodes, %d elements.", mesh->getNNodes(), mesh->getNElements()); + + // write into a file + FileIO::Legacy::MeshIO meshIO; + meshIO.setMesh(mesh); + meshIO.writeToFile(mesh_out.getValue()); + + delete mesh; + } + + delete custom_format; + delete logog_cout; + LOGOG_SHUTDOWN(); + + return 1; +} +