From 05a7f742b70c576b6ea31cf7a278e15b25510c6e Mon Sep 17 00:00:00 2001 From: Norihiro Watanabe <norihiro.watanabe@ufz.de> Date: Tue, 25 Oct 2016 16:54:15 +0200 Subject: [PATCH] [App/Utils] add the new tool createQuadraticMesh --- Applications/Utils/MeshEdit/CMakeLists.txt | 5 + .../Utils/MeshEdit/createQuadraticeMesh.cpp | 163 ++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 Applications/Utils/MeshEdit/createQuadraticeMesh.cpp diff --git a/Applications/Utils/MeshEdit/CMakeLists.txt b/Applications/Utils/MeshEdit/CMakeLists.txt index a44be8c211e..35ef24556d8 100644 --- a/Applications/Utils/MeshEdit/CMakeLists.txt +++ b/Applications/Utils/MeshEdit/CMakeLists.txt @@ -81,6 +81,10 @@ add_executable(swapNodeCoordinateAxes swapNodeCoordinateAxes.cpp) target_link_libraries(swapNodeCoordinateAxes MeshLib) set_target_properties(swapNodeCoordinateAxes PROPERTIES FOLDER Utilities) +add_executable(createQuadraticeMesh createQuadraticeMesh.cpp ) +target_link_libraries(createQuadraticeMesh MeshLib) +set_target_properties(createQuadraticeMesh PROPERTIES FOLDER Utilities) + #################### ### Installation ### #################### @@ -90,6 +94,7 @@ install(TARGETS checkMesh CreateBoundaryConditionsAlongPolylines createLayeredMeshFromRasters + createQuadraticeMesh editMaterialID ExtractSurface MapGeometryToMeshSurface diff --git a/Applications/Utils/MeshEdit/createQuadraticeMesh.cpp b/Applications/Utils/MeshEdit/createQuadraticeMesh.cpp new file mode 100644 index 00000000000..47486c281f5 --- /dev/null +++ b/Applications/Utils/MeshEdit/createQuadraticeMesh.cpp @@ -0,0 +1,163 @@ +/** + * @copyright + * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + * + */ + +#include <memory> +#include <string> + +#include <tclap/CmdLine.h> + +#include "Applications/ApplicationsLib/LogogSetup.h" + +#include "BaseLib/BuildInfo.h" +#include "BaseLib/makeVectorUnique.h" + +#include "MeshLib/Mesh.h" +#include "MeshLib/Node.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/Elements/Line.h" +#include "MeshLib/Elements/Quad.h" +#include "MeshLib/MeshEditing/DuplicateMeshComponents.h" +#include "MeshLib/Properties.h" +#include "MeshLib/PropertyVector.h" + +#include "MeshLib/IO/readMeshFromFile.h" +#include "MeshLib/IO/writeMeshToFile.h" + +namespace +{ + +struct Edge +{ + Edge(std::size_t id1, std::size_t id2) + : _id1(std::min(id1, id2)), _id2(std::max(id1, id2)) + {} + + bool operator==(Edge const& r) const + { + return (_id1 == r._id1 && _id2 == r._id2); + } + + std::size_t _id1; + std::size_t _id2; + + std::size_t _edge_id = 0; +}; + +bool operator< (Edge const& l, Edge const& r) +{ + return (l._id1 != r._id1) ? (l._id1 < r._id1) : l._id2 < r._id2; +} + +template <typename T_ELEMENT> +T_ELEMENT* createQuadraticElement(MeshLib::Element const* e, std::vector<Edge> const& vec_edges, + std::vector<MeshLib::Node*> const& vec_new_nodes, const std::size_t n_mesh_base_nodes) +{ + auto const n_all_nodes = T_ELEMENT::n_all_nodes; + auto const n_base_nodes = T_ELEMENT::n_base_nodes; + MeshLib::Node** nodes = new MeshLib::Node*[n_all_nodes]; + for (unsigned i=0; i<e->getNumberOfBaseNodes(); i++) + nodes[i] = const_cast<MeshLib::Node*>(e->getNode(i)); + for (unsigned i=0; i<e->getNumberOfEdges(); i++) + { + auto itr = std::find(vec_edges.begin(), vec_edges.end(), + Edge(e->getEdgeNode(i, 0)->getID(), + e->getEdgeNode(i, 1)->getID())); + assert(itr != vec_edges.end()); + nodes[n_base_nodes + i] = + vec_new_nodes[n_mesh_base_nodes + itr->_edge_id]; + } + return new T_ELEMENT(nodes); +} + + +static std::unique_ptr<MeshLib::Mesh> createQuadraticOrderMesh(MeshLib::Mesh const& org_mesh) +{ + std::vector<MeshLib::Node*> vec_new_nodes = MeshLib::copyNodeVector(org_mesh.getNodes()); + + // collect edges + std::vector<Edge> vec_edges; + for (MeshLib::Element const* e : org_mesh.getElements()) + { + for (unsigned i=0; i<e->getNumberOfEdges(); i++) + { + auto node0 = e->getEdgeNode(i, 0); + auto node1 = e->getEdgeNode(i, 1); + vec_edges.emplace_back(node0->getID(), node1->getID()); + } + } + BaseLib::makeVectorUnique(vec_edges); + for (std::size_t i=0; i<vec_edges.size(); i++) + vec_edges[i]._edge_id = i; + INFO("Found %d edges in the mesh", vec_edges.size()); + + // create mid-point nodes + double coords[3]; + for (Edge const& edge : vec_edges) + { + auto const& node0 = *vec_new_nodes[edge._id1]; + auto const& node1 = *vec_new_nodes[edge._id2]; + for (unsigned i=0; i<3; i++) + coords[i] = (node0[i] + node1[i]) * 0.5; + vec_new_nodes.push_back(new MeshLib::Node(coords)); + } + + // create new elements with the quadratic nodes + std::vector<MeshLib::Element*> vec_new_eles; + for (MeshLib::Element const* e : org_mesh.getElements()) + { + if (e->getCellType() == MeshLib::CellType::LINE2) + { + vec_new_eles.push_back(createQuadraticElement<MeshLib::Line3>( + e, vec_edges, vec_new_nodes, org_mesh.getNumberOfNodes())); + } + else if (e->getCellType() == MeshLib::CellType::QUAD4) + { + vec_new_eles.push_back(createQuadraticElement<MeshLib::Quad8>( + e, vec_edges, vec_new_nodes, org_mesh.getNumberOfNodes())); + } + else + { + OGS_FATAL("Mesh element type %s is not supported", MeshLib::CellType2String(e->getCellType()).c_str()); + } + } + + std::unique_ptr<MeshLib::Mesh> new_mesh( + new MeshLib::Mesh(org_mesh.getName(), vec_new_nodes, vec_new_eles, + org_mesh.getProperties().excludeCopyProperties( + std::vector<MeshLib::MeshItemType>( + 1, MeshLib::MeshItemType::Node)))); + return new_mesh; +} + +} // no named namespace + +int main(int argc, char *argv[]) +{ + ApplicationsLib::LogogSetup logog_setup; + + TCLAP::CmdLine cmd("Create quadratic order mesh", ' ', BaseLib::BuildInfo::git_describe); + TCLAP::ValueArg<std::string> input_arg("i", "input-mesh-file","input mesh file",true,"","string"); + cmd.add( input_arg ); + TCLAP::ValueArg<std::string> output_arg("o", "output-mesh-file","output mesh file",true,"","string"); + cmd.add( output_arg ); + cmd.parse( argc, argv ); + + std::unique_ptr<MeshLib::Mesh> mesh( + MeshLib::IO::readMeshFromFile(input_arg.getValue())); + if (!mesh) + return EXIT_FAILURE; + + INFO("Create a quadratic order mesh"); + auto new_mesh(createQuadraticOrderMesh(*mesh)); + + INFO("Save the new mesh into a file"); + MeshLib::IO::writeMeshToFile(*new_mesh, output_arg.getValue()); + + return EXIT_SUCCESS; +} -- GitLab