From 3c6a1ee5eccaaa434b19b6d9da83432afe716abb Mon Sep 17 00:00:00 2001 From: Norihiro Watanabe <norihiro.watanabe@ufz.de> Date: Thu, 4 Sep 2014 19:08:13 +0200 Subject: [PATCH] introduce BoundaryElementsAlongPolyline and BoundaryElementsAlongSurface to own boundary elements --- .../BoundaryElementsAlongPolyline.cpp | 67 +++++++++++++++ .../BoundaryElementsAlongPolyline.h | 69 ++++++++++++++++ .../BoundaryElementsAlongSurface.cpp | 56 +++++++++++++ .../BoundaryElementsAlongSurface.h | 69 ++++++++++++++++ MeshGeoToolsLib/BoundaryElementsSearcher.cpp | 81 ++++++++++++------- MeshGeoToolsLib/BoundaryElementsSearcher.h | 45 +++++++---- 6 files changed, 341 insertions(+), 46 deletions(-) create mode 100644 MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp create mode 100644 MeshGeoToolsLib/BoundaryElementsAlongPolyline.h create mode 100644 MeshGeoToolsLib/BoundaryElementsAlongSurface.cpp create mode 100644 MeshGeoToolsLib/BoundaryElementsAlongSurface.h diff --git a/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp new file mode 100644 index 00000000000..8c5ef49e5cb --- /dev/null +++ b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp @@ -0,0 +1,67 @@ +/** + * @copyright + * Copyright (c) 2012-2014, 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 "BoundaryElementsAlongPolyline.h" + +#include "GeoLib/Polyline.h" + +#include "MeshLib/Mesh.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshSearcher.h" + +#include "MeshGeoToolsLib/MeshNodeSearcher.h" + +namespace MeshGeoToolsLib +{ + +BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Polyline const& ply) +: _mesh(mesh), _ply(ply) +{ + // search elements near the polyline + auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply); + auto ele_ids_near_poly = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_poly); + + // get a list of edges made of the nodes + for (auto ele_id : ele_ids_near_poly) { + auto* e = _mesh.getElement(ele_id); + // skip internal elements + bool isOuterElement = false; + for (unsigned i=0; i<e->getNNeighbors(); i++) { + if (!e->getNeighbor(i)) { + isOuterElement = true; + break; + } + } + if (!isOuterElement) + continue; + // find edges on polyline + for (unsigned i=0; i<e->getNEdges(); i++) { + auto* edge = e->getEdge(i); + // check + size_t cnt_match = 0; + for (size_t j=0; j<edge->getNNodes(); j++) { + if (std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), edge->getNodeIndex(j)) != node_ids_on_poly.end()) + cnt_match++; + else + break; + } + // update the list + if (cnt_match==edge->getNNodes()) + _boundary_elements.push_back(const_cast<MeshLib::Element*>(edge)); + } + } +} + +BoundaryElementsAlongPolyline::~BoundaryElementsAlongPolyline() +{ + for (auto p : _boundary_elements) + delete p; +} + +} // end namespace MeshGeoTools + diff --git a/MeshGeoToolsLib/BoundaryElementsAlongPolyline.h b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.h new file mode 100644 index 00000000000..3374d0a7a7f --- /dev/null +++ b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.h @@ -0,0 +1,69 @@ +/** + * @copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ +#ifndef BOUNDARYELEMENTSALONGPOLYLINE_H_ +#define BOUNDARYELEMENTSALONGPOLYLINE_H_ + +#include <vector> + +namespace GeoLib +{ +class Polyline; +} + +namespace MeshLib +{ +class Mesh; +class Element; +} + +namespace MeshGeoToolsLib +{ +class MeshNodeSearcher; + +/** + * This class collects element edges located along a polyline. + * Note that internal edges are not collected in this class. + */ +class BoundaryElementsAlongPolyline +{ +public: + /** + * Constructor + * @param mesh a mesh object + * @param mshNodeSearcher a MeshNodeSearcher object which is internally used to search mesh nodes + * @param ply a polyline object where edges are searched + */ + BoundaryElementsAlongPolyline(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Polyline const& ply); + + /// destructor + virtual ~BoundaryElementsAlongPolyline(); + + /// return the mesh object + MeshLib::Mesh const& getMesh() const {return _mesh;} + + /** + * Deploying this method the user can get access to the underlying + * GeoLib::Polyline. + * @return the underlying GeoLib::Polyline + */ + GeoLib::Polyline const& getPolyline () const {return _ply;} + + /** + * Return the vector of boundary elements + */ + std::vector<MeshLib::Element*> const& getBoundaryElements() const {return _boundary_elements; } + +private: + MeshLib::Mesh const& _mesh; + GeoLib::Polyline const& _ply; + std::vector<MeshLib::Element*> _boundary_elements; +}; + +} // end namespace MeshGeoTools + +#endif /* BOUNDARYELEMENTSALONGPOLYLINE_H_ */ diff --git a/MeshGeoToolsLib/BoundaryElementsAlongSurface.cpp b/MeshGeoToolsLib/BoundaryElementsAlongSurface.cpp new file mode 100644 index 00000000000..2c8e4511aab --- /dev/null +++ b/MeshGeoToolsLib/BoundaryElementsAlongSurface.cpp @@ -0,0 +1,56 @@ +/** + * @copyright + * Copyright (c) 2012-2014, 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 "BoundaryElementsAlongSurface.h" + +#include "GeoLib/Surface.h" + +#include "MeshLib/Mesh.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshSearcher.h" + +#include "MeshGeoToolsLib/MeshNodeSearcher.h" + +namespace MeshGeoToolsLib +{ + +BoundaryElementsAlongSurface::BoundaryElementsAlongSurface(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Surface const& sfc) +: _mesh(mesh), _sfc(sfc) +{ + // search elements near the polyline + auto node_ids_on_sfc = mshNodeSearcher.getMeshNodeIDsAlongSurface(sfc); + auto ele_ids_near_sfc = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_sfc); + + // get a list of edges made of the nodes + for (auto ele_id : ele_ids_near_sfc) { + auto* e = _mesh.getElement(ele_id); + for (unsigned i=0; i<e->getNEdges(); i++) { + auto* edge = e->getEdge(i); + // check + size_t cnt_match = 0; + for (size_t j=0; j<edge->getNNodes(); j++) { + if (std::find(node_ids_on_sfc.begin(), node_ids_on_sfc.end(), edge->getNodeIndex(j)) != node_ids_on_sfc.end()) + cnt_match++; + else + break; + } + // update the list + if (cnt_match==edge->getNNodes()) + _boundary_elements.push_back(const_cast<MeshLib::Element*>(edge)); + } + } +} + +BoundaryElementsAlongSurface::~BoundaryElementsAlongSurface() +{ + for (auto p : _boundary_elements) + delete p; +} + +} // end namespace MeshGeoTools + diff --git a/MeshGeoToolsLib/BoundaryElementsAlongSurface.h b/MeshGeoToolsLib/BoundaryElementsAlongSurface.h new file mode 100644 index 00000000000..c4d4e209f58 --- /dev/null +++ b/MeshGeoToolsLib/BoundaryElementsAlongSurface.h @@ -0,0 +1,69 @@ +/** + * @copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ +#ifndef BOUNDARYELEMENTSALONGSURFACE_H_ +#define BOUNDARYELEMENTSALONGSURFACE_H_ + +#include <vector> + +namespace GeoLib +{ +class Surface; +} + +namespace MeshLib +{ +class Mesh; +class Element; +} + +namespace MeshGeoToolsLib +{ +class MeshNodeSearcher; + +/** + * This class collects element faces located along a surface. + * Note that internal faces are not collected in this class. + */ +class BoundaryElementsAlongSurface +{ +public: + /** + * Constructor + * @param mesh a mesh object + * @param mshNodeSearcher a MeshNodeSearcher object which is internally used to search mesh nodes + * @param sfc a surface object where face elements are searched for + */ + BoundaryElementsAlongSurface(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Surface const& sfc); + + /// destructor + virtual ~BoundaryElementsAlongSurface(); + + /// return the mesh object + MeshLib::Mesh const& getMesh() const {return _mesh;} + + /** + * Deploying this method the user can get access to the underlying + * GeoLib::Surface. + * @return the underlying GeoLib::Surface + */ + GeoLib::Surface const& getSurface() const {return _sfc;} + + /** + * Return the vector of boundary elements + */ + std::vector<MeshLib::Element*> const& getBoundaryElements() const {return _boundary_elements;} + +private: + MeshLib::Mesh const& _mesh; + GeoLib::Surface const& _sfc; + std::vector<MeshLib::Element*> _boundary_elements; +}; + +} // end namespace MeshGeoTools + +#endif /* BOUNDARYELEMENTSALONGSURFACE_H_ */ diff --git a/MeshGeoToolsLib/BoundaryElementsSearcher.cpp b/MeshGeoToolsLib/BoundaryElementsSearcher.cpp index 6a39db82578..5b623037bcb 100644 --- a/MeshGeoToolsLib/BoundaryElementsSearcher.cpp +++ b/MeshGeoToolsLib/BoundaryElementsSearcher.cpp @@ -1,6 +1,6 @@ /** * @copyright - * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/LICENSE.txt @@ -8,58 +8,77 @@ #include "BoundaryElementsSearcher.h" +#include "GeoLib/GeoObject.h" +#include "GeoLib/Polyline.h" +#include "GeoLib/Surface.h" + +#include "MeshLib/Mesh.h" #include "MeshLib/Elements/Element.h" #include "MeshLib/MeshSearcher.h" +#include "MeshGeoToolsLib/MeshNodeSearcher.h" +#include "MeshGeoToolsLib/BoundaryElementsAlongPolyline.h" +#include "MeshGeoToolsLib/BoundaryElementsAlongSurface.h" + + namespace MeshGeoToolsLib { BoundaryElementsSearcher::BoundaryElementsSearcher(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher) : _mesh(mesh), _mshNodeSearcher(mshNodeSearcher) {} -std::vector<MeshLib::Element*> BoundaryElementsSearcher::getBoundaryElements(GeoLib::GeoObject const& geoObj) +BoundaryElementsSearcher::~BoundaryElementsSearcher() +{ + for (auto p : _boundary_elements_along_polylines) + delete p; + for (auto p : _boundary_elements_along_surfaces) + delete p; +} + +std::vector<MeshLib::Element*> const& BoundaryElementsSearcher::getBoundaryElements(GeoLib::GeoObject const& geoObj) { - std::vector<MeshLib::Element*> vec_elements; switch (geoObj.getGeoType()) { case GeoLib::GEOTYPE::POLYLINE: - vec_elements = this->getBoundaryElementsAlongPolyline(*dynamic_cast<const GeoLib::Polyline*>(&geoObj)); + return this->getBoundaryElementsAlongPolyline(*dynamic_cast<const GeoLib::Polyline*>(&geoObj)); break; - default: + case GeoLib::GEOTYPE::SURFACE: + return this->getBoundaryElementsAlongSurface(*dynamic_cast<const GeoLib::Surface*>(&geoObj)); break; + default: + const static std::vector<MeshLib::Element*> dummy; + return dummy; } - return vec_elements; } -std::vector<MeshLib::Element*> BoundaryElementsSearcher::getBoundaryElementsAlongPolyline(GeoLib::Polyline const& ply) +std::vector<MeshLib::Element*> const& BoundaryElementsSearcher::getBoundaryElementsAlongPolyline(GeoLib::Polyline const& ply) { - // serach elements near the polyline - auto node_ids_on_poly = _mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply); - auto ele_ids_near_poly = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_poly); - - // get a list of edges made of the nodes - std::vector<MeshLib::Element*> vec_edges_on_poly; - for (auto ele_id : ele_ids_near_poly) { - auto* e = _mesh.getElement(ele_id); - for (unsigned i=0; i<e->getNEdges(); i++) { - auto* edge = e->getEdge(i); - //TODO where should we store and delete this new object? - //TODO avoid duplicated entries - // check - size_t cnt_match = 0; - for (size_t j=0; j<edge->getNNodes(); j++) { - if (std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), edge->getNodeIndex(j)) != node_ids_on_poly.end()) - cnt_match++; - else - break; - } - // update the list - if (cnt_match==edge->getNNodes()) - vec_edges_on_poly.push_back(const_cast<MeshLib::Element*>(edge)); + std::vector<BoundaryElementsAlongPolyline*>::const_iterator it(_boundary_elements_along_polylines.begin()); + for (; it != _boundary_elements_along_polylines.end(); ++it) { + if (&(*it)->getPolyline() == &ply) { + // we calculated mesh nodes for this polyline already + return (*it)->getBoundaryElements(); } } - return vec_edges_on_poly; + + _boundary_elements_along_polylines.push_back( + new BoundaryElementsAlongPolyline(_mesh, _mshNodeSearcher, ply)); + return _boundary_elements_along_polylines.back()->getBoundaryElements(); } +std::vector<MeshLib::Element*> const& BoundaryElementsSearcher::getBoundaryElementsAlongSurface(GeoLib::Surface const& sfc) +{ + std::vector<BoundaryElementsAlongSurface*>::const_iterator it(_boundary_elements_along_surfaces.begin()); + for (; it != _boundary_elements_along_surfaces.end(); ++it) { + if (&(*it)->getSurface() == &sfc) { + // we calculated mesh nodes for this surface already + return (*it)->getBoundaryElements(); + } + } + + _boundary_elements_along_surfaces.push_back( + new BoundaryElementsAlongSurface(_mesh, _mshNodeSearcher, sfc)); + return _boundary_elements_along_surfaces.back()->getBoundaryElements(); +} } // end namespace MeshGeoTools diff --git a/MeshGeoToolsLib/BoundaryElementsSearcher.h b/MeshGeoToolsLib/BoundaryElementsSearcher.h index 3dc41aabec8..98f083b344f 100644 --- a/MeshGeoToolsLib/BoundaryElementsSearcher.h +++ b/MeshGeoToolsLib/BoundaryElementsSearcher.h @@ -1,6 +1,6 @@ /** * @copyright - * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/LICENSE.txt @@ -10,23 +10,28 @@ #include <vector> -// GeoLib -#include "Point.h" -#include "Polyline.h" - -// MeshLib -#include "Mesh.h" -#include "Node.h" +namespace GeoLib +{ +class GeoObject; +class Polyline; +class Surface; +} -// MeshGeoToolsLib -#include "MeshNodeSearcher.h" +namespace MeshLib +{ +class Mesh; +class Element; +} namespace MeshGeoToolsLib { +class MeshNodeSearcher; +class BoundaryElementsAlongPolyline; +class BoundaryElementsAlongSurface; /** - * This class searches and creates boundary elements located on a given geometric object. - * Boundary elements will be created from edges or faces of existing domain elements. + * This class searches boundary elements located on a given geometric object, i.e. polyline and surface. + * Note that internal boundaries are currently not supported. */ class BoundaryElementsSearcher { @@ -39,7 +44,7 @@ public: BoundaryElementsSearcher(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher); /// destructor - virtual ~BoundaryElementsSearcher() {} + virtual ~BoundaryElementsSearcher(); /** * generate boundary elements on the given geometric object (point, polyline, surface). @@ -47,18 +52,28 @@ public: * @param geoObj a GeoLib::GeoObject where the nearest mesh node is searched for * @return a vector of boundary element objects */ - std::vector<MeshLib::Element*> getBoundaryElements(GeoLib::GeoObject const& geoObj); + std::vector<MeshLib::Element*> const& getBoundaryElements(GeoLib::GeoObject const& geoObj); /** * generate boundary elements on the given polyline. * @param ply the GeoLib::Polyline the nearest mesh nodes are searched for * @return a vector of boundary element objects */ - std::vector<MeshLib::Element*> getBoundaryElementsAlongPolyline(GeoLib::Polyline const& ply); + std::vector<MeshLib::Element*> const& getBoundaryElementsAlongPolyline(GeoLib::Polyline const& ply); + + /** + * generate boundary elements on the given surface. + * @param sfc the GeoLib::Surface the nearest mesh nodes are searched for + * @return a vector of boundary element objects + */ + std::vector<MeshLib::Element*> const& getBoundaryElementsAlongSurface(GeoLib::Surface const& sfc); + private: MeshLib::Mesh const& _mesh; MeshNodeSearcher &_mshNodeSearcher; + std::vector<BoundaryElementsAlongPolyline*> _boundary_elements_along_polylines; + std::vector<BoundaryElementsAlongSurface*> _boundary_elements_along_surfaces; }; } // end namespace MeshGeoTools -- GitLab