Skip to content
Snippets Groups Projects
Commit 25518eac authored by Tom Fischer's avatar Tom Fischer
Browse files

Merge pull request #455 from norihiro-w/gen-boundary-ele

Boundary element generator
parents 2db65c21 58240ebe
No related branches found
No related tags found
No related merge requests found
/**
* @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 <algorithm>
#include "GeoLib/Polyline.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "MeshLib/Elements/Element.h"
#include "MeshLib/Elements/Line.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 nodes and elements located along the polyline
auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply);
auto ele_ids_near_ply = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_poly);
// check all edges of the elements near the polyline
for (auto ele_id : ele_ids_near_ply) {
auto* e = _mesh.getElement(ele_id);
// skip internal elements
if (!e->isBoundaryElement())
continue;
// find edges on the polyline
for (unsigned i=0; i<e->getNEdges(); i++) {
auto* edge = e->getEdge(i);
// check if all edge nodes are along the polyline (if yes, store a distance)
std::vector<std::size_t> edge_node_distances_along_ply;
if (includesAllEdgeNodeIDs(node_ids_on_poly, *edge, edge_node_distances_along_ply)) {
auto* new_edge = modifyEdgeNodeOrdering(*edge, ply, edge_node_distances_along_ply, node_ids_on_poly);
if (edge != new_edge)
delete edge;
_boundary_elements.push_back(new_edge);
} else {
delete edge;
}
}
}
// sort picked edges according to a distance of their first node along the polyline
std::sort(_boundary_elements.begin(), _boundary_elements.end(),
[&](MeshLib::Element*e1, MeshLib::Element*e2)
{
std::size_t dist1 = std::distance(node_ids_on_poly.begin(),
std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), e1->getNodeIndex(0)));
std::size_t dist2 = std::distance(node_ids_on_poly.begin(),
std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), e2->getNodeIndex(0)));
return (dist1 < dist2);
});
}
BoundaryElementsAlongPolyline::~BoundaryElementsAlongPolyline()
{
for (auto p : _boundary_elements)
delete p;
}
bool BoundaryElementsAlongPolyline::includesAllEdgeNodeIDs(const std::vector<std::size_t> &vec_node_ids, const MeshLib::Element &edge, std::vector<std::size_t> &edge_node_distances) const
{
unsigned j=0;
for (; j<edge.getNNodes(); j++) {
auto itr = std::find(vec_node_ids.begin(), vec_node_ids.end(), edge.getNodeIndex(j));
if (itr != vec_node_ids.end())
edge_node_distances.push_back(std::distance(vec_node_ids.begin(), itr));
else
break;
}
return (j==edge.getNNodes());
}
MeshLib::Element* BoundaryElementsAlongPolyline::modifyEdgeNodeOrdering(const MeshLib::Element &edge, const GeoLib::Polyline &ply, const std::vector<std::size_t> &edge_node_distances_along_ply, const std::vector<std::size_t> &node_ids_on_poly) const
{
MeshLib::Element* new_edge = const_cast<MeshLib::Element*>(&edge);
// The first node of the edge should be always closer to the beginning of the polyline than other nodes.
// Otherwise, create a new element with reversed local node index
if (edge_node_distances_along_ply.front() > edge_node_distances_along_ply.back()
|| (ply.isClosed() && edge_node_distances_along_ply.back() == node_ids_on_poly.size()-1)) {
MeshLib::Node** new_nodes = new MeshLib::Node*[edge.getNNodes()];
std::reverse_copy(edge.getNodes(), edge.getNodes()+edge.getNNodes(), new_nodes);
new_edge = new MeshLib::Line(new_nodes);
}
return new_edge;
}
} // end namespace MeshGeoTools
/**
* @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 (i.e. edges). The elements are sorted
* according to their distance to the starting point of the given polyline.
*/
std::vector<MeshLib::Element*> const& getBoundaryElements() const {return _boundary_elements; }
private:
/**
* Check if a vector of node IDs includes all nodes of a given element
* @param vec_node_ids a vector of Node IDs
* @param edge Edge object whose node IDs are checked
* @param edge_node_distances a vector of distances of the edge nodes from the beginning of the given node ID vector
* @return true if all element nodes are included in the vector
*/
bool includesAllEdgeNodeIDs(const std::vector<std::size_t> &vec_node_ids, const MeshLib::Element &edge, std::vector<std::size_t> &edge_node_distances) const;
/**
* Modify node ordering of an edge so that its first node is closer to the beginning of a polyline than others
* @param edge Element object
* @param ply Polyline object
* @param edge_node_distances_along_ply A vector of current edge node distances along poly
* @param node_ids_on_poly A vector of node IDs along the polyine
* @return A pointer to the new modified edge object. A pointer to the original edge is returned if the modification is unnecessary.
*/
MeshLib::Element* modifyEdgeNodeOrdering(const MeshLib::Element &edge, const GeoLib::Polyline &ply, const std::vector<std::size_t> &edge_node_distances_along_ply, const std::vector<std::size_t> &node_ids_on_poly) const;
MeshLib::Mesh const& _mesh;
GeoLib::Polyline const& _ply;
std::vector<MeshLib::Element*> _boundary_elements;
};
} // end namespace MeshGeoTools
#endif /* BOUNDARYELEMENTSALONGPOLYLINE_H_ */
/**
* @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 "BoundaryElementsOnSurface.h"
#include "GeoLib/Surface.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshSearcher.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h"
namespace MeshGeoToolsLib
{
BoundaryElementsOnSurface::BoundaryElementsOnSurface(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 faces made of the nodes
for (auto ele_id : ele_ids_near_sfc) {
auto* e = _mesh.getElement(ele_id);
// skip internal elements
if (!e->isBoundaryElement())
continue;
// find faces on surface
for (unsigned i=0; i<e->getNFaces(); i++) {
auto* face = e->getFace(i);
// check
size_t cnt_match = 0;
for (size_t j=0; j<face->getNNodes(); j++) {
if (std::find(node_ids_on_sfc.begin(), node_ids_on_sfc.end(), face->getNodeIndex(j)) != node_ids_on_sfc.end())
cnt_match++;
else
break;
}
// update the list
if (cnt_match==face->getNNodes())
_boundary_elements.push_back(const_cast<MeshLib::Element*>(face));
else
delete face;
}
}
}
BoundaryElementsOnSurface::~BoundaryElementsOnSurface()
{
for (auto p : _boundary_elements)
delete p;
}
} // end namespace MeshGeoTools
/**
* @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 BOUNDARYELEMENTSONSURFACE_H_
#define BOUNDARYELEMENTSONSURFACE_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 BoundaryElementsOnSurface
{
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
*/
BoundaryElementsOnSurface(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Surface const& sfc);
/// destructor
virtual ~BoundaryElementsOnSurface();
/// 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 (i.e. faces). The elements are unsorted.
*/
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 /* BOUNDARYELEMENTSONSURFACE_H_ */
/**
* @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 "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/BoundaryElementsOnSurface.h"
namespace MeshGeoToolsLib
{
BoundaryElementsSearcher::BoundaryElementsSearcher(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher) : _mesh(mesh), _mshNodeSearcher(mshNodeSearcher)
{}
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)
{
switch (geoObj.getGeoType()) {
case GeoLib::GEOTYPE::POLYLINE:
return this->getBoundaryElementsAlongPolyline(*dynamic_cast<const GeoLib::Polyline*>(&geoObj));
break;
case GeoLib::GEOTYPE::SURFACE:
return this->getBoundaryElementsOnSurface(*dynamic_cast<const GeoLib::Surface*>(&geoObj));
break;
default:
const static std::vector<MeshLib::Element*> dummy;
return dummy;
}
}
std::vector<MeshLib::Element*> const& BoundaryElementsSearcher::getBoundaryElementsAlongPolyline(GeoLib::Polyline const& ply)
{
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();
}
}
_boundary_elements_along_polylines.push_back(
new BoundaryElementsAlongPolyline(_mesh, _mshNodeSearcher, ply));
return _boundary_elements_along_polylines.back()->getBoundaryElements();
}
std::vector<MeshLib::Element*> const& BoundaryElementsSearcher::getBoundaryElementsOnSurface(GeoLib::Surface const& sfc)
{
std::vector<BoundaryElementsOnSurface*>::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 BoundaryElementsOnSurface(_mesh, _mshNodeSearcher, sfc));
return _boundary_elements_along_surfaces.back()->getBoundaryElements();
}
} // end namespace MeshGeoTools
/**
* @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 BOUNDARYELEMENTSSEARCHER_H_
#define BOUNDARYELEMENTSSEARCHER_H_
#include <vector>
namespace GeoLib
{
class GeoObject;
class Polyline;
class Surface;
}
namespace MeshLib
{
class Mesh;
class Element;
}
namespace MeshGeoToolsLib
{
class MeshNodeSearcher;
class BoundaryElementsAlongPolyline;
class BoundaryElementsOnSurface;
/**
* 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
{
public:
/**
* Constructor
* @param mesh a mesh object
* @param mshNodeSearcher a MeshNodeSearcher object which is internally used to search mesh nodes
*/
BoundaryElementsSearcher(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher);
/// destructor
virtual ~BoundaryElementsSearcher();
/**
* generate boundary elements on the given geometric object (point, polyline, surface).
*
* @param geoObj a GeoLib::GeoObject where the nearest mesh node is searched for
* @return a vector of boundary element objects
*/
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*> 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& getBoundaryElementsOnSurface(GeoLib::Surface const& sfc);
private:
MeshLib::Mesh const& _mesh;
MeshNodeSearcher &_mshNodeSearcher;
std::vector<BoundaryElementsAlongPolyline*> _boundary_elements_along_polylines;
std::vector<BoundaryElementsOnSurface*> _boundary_elements_along_surfaces;
};
} // end namespace MeshGeoTools
#endif /* BOUNDARYELEMENTSSEARCHER_H_ */
/**
* \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/project/license
*
*/
#include "MeshSearcher.h"
#include "Mesh.h"
#include "Node.h"
#include "Elements/Element.h"
#include <algorithm>
namespace MeshLib
{
std::vector<std::size_t> getConnectedElementIDs(MeshLib::Mesh const& msh, const std::vector<std::size_t> &nodes)
{
std::vector<std::size_t> connected_elements;
std::for_each(nodes.begin(), nodes.end(),
[&](std::size_t node_id)
{
for (auto* e : msh.getNode(node_id)->getElements()) {
connected_elements.push_back(e->getID());
}
});
std::sort(connected_elements.begin(), connected_elements.end());
auto it = std::unique(connected_elements.begin(), connected_elements.end());
connected_elements.resize(std::distance(connected_elements.begin(),it));
return connected_elements;
}
std::vector<std::size_t> getConnectedNodeIDs(const std::vector<MeshLib::Element*> &elements)
{
std::vector<std::size_t> connected_nodes;
std::for_each(elements.begin(), elements.end(),
[&](MeshLib::Element* e)
{
for (unsigned i=0; i<e->getNNodes(); i++)
connected_nodes.push_back(e->getNodeIndex(i));
});
std::sort(connected_nodes.begin(), connected_nodes.end());
auto it = std::unique(connected_nodes.begin(), connected_nodes.end());
connected_nodes.resize(std::distance(connected_nodes.begin(),it));
return connected_nodes;
}
} // end namespace MeshLib
/**
* \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/project/license
*
*/
#ifndef MESHSEARCHER_H_
#define MESHSEARCHER_H_
#include <vector>
namespace MeshLib
{
// forward declarations
class Mesh;
class Element;
/**
* get a vector of elements connected to given nodes
* @param msh a mesh object
* @param node_ids a vector of mesh node ids
* @return a vector of element ids which connect to the given nodes
*/
std::vector<std::size_t> getConnectedElementIDs(MeshLib::Mesh const& msh, const std::vector<std::size_t> &node_ids);
/**
* get a vector of node ID connected to given elements
* @param elements a vector of a pointer to a mesh element object
* @return a vector of node ID
*/
std::vector<std::size_t> getConnectedNodeIDs(const std::vector<MeshLib::Element*> &elements);
} // end namespace MeshLib
#endif //MESHSEARCHER_H_
/**
* @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 "gtest/gtest.h"
#include <memory>
#include "MeshLib/Mesh.h"
#include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshLib/MeshSearcher.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h"
#include "MeshGeoToolsLib/BoundaryElementsSearcher.h"
using namespace MeshLib;
class MeshLibBoundaryElementSearchInSimpleQuadMesh : public testing::Test
{
public:
MeshLibBoundaryElementSearchInSimpleQuadMesh() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_quad_mesh(MeshGenerator::generateRegularQuadMesh(_geometric_size, _number_of_subdivisions_per_direction))
{}
~MeshLibBoundaryElementSearchInSimpleQuadMesh()
{
delete _quad_mesh;
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
Mesh* _quad_mesh;
};
class MeshLibBoundaryElementSearchInSimpleHexMesh : public testing::Test
{
public:
MeshLibBoundaryElementSearchInSimpleHexMesh() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_hex_mesh(MeshGenerator::generateRegularHexMesh(_geometric_size, _number_of_subdivisions_per_direction))
{}
~MeshLibBoundaryElementSearchInSimpleHexMesh()
{
delete _hex_mesh;
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
Mesh* _hex_mesh;
};
TEST_F(MeshLibBoundaryElementSearchInSimpleQuadMesh, PolylineSearch)
{
ASSERT_TRUE(_quad_mesh != nullptr);
const unsigned n_eles_per_dir = _number_of_subdivisions_per_direction;
const unsigned n_nodes_per_dir = _number_of_subdivisions_per_direction + 1;
// create a polyline (closed)
std::vector<GeoLib::Point*> pnts;
pnts.push_back(new GeoLib::Point(0.0, 0.0, 0.0));
pnts.push_back(new GeoLib::Point(_geometric_size, 0.0, 0.0));
pnts.push_back(new GeoLib::Point(_geometric_size, _geometric_size, 0.0));
pnts.push_back(new GeoLib::Point(0.0, _geometric_size, 0.0));
GeoLib::Polyline ply0(pnts);
ply0.addPoint(0);
ply0.addPoint(1);
ply0.addPoint(2);
ply0.addPoint(3);
ply0.addPoint(0);
// perform search on the polyline
MeshGeoToolsLib::MeshNodeSearcher mesh_node_searcher(*_quad_mesh);
MeshGeoToolsLib::BoundaryElementsSearcher boundary_element_searcher(*_quad_mesh, mesh_node_searcher);
std::vector<MeshLib::Element*> const& found_edges_ply0(boundary_element_searcher.getBoundaryElements(ply0));
// check the total number of found edges
ASSERT_EQ(n_eles_per_dir*4u, found_edges_ply0.size());
// check node IDs of edges
for (unsigned i=0; i<n_eles_per_dir; i++) {
// edge found on a bottom line
auto* edge0 = found_edges_ply0[i];
ASSERT_EQ(2u, edge0->getNNodes());
ASSERT_EQ(i, edge0->getNodeIndex(0));
ASSERT_EQ(i+1, edge0->getNodeIndex(1));
// edge found on a right line
auto* edge1 = found_edges_ply0[i+n_eles_per_dir];
ASSERT_EQ(2u, edge1->getNNodes());
ASSERT_EQ(n_nodes_per_dir*i+n_nodes_per_dir-1, edge1->getNodeIndex(0));
ASSERT_EQ(n_nodes_per_dir*(i+1)+n_nodes_per_dir-1, edge1->getNodeIndex(1));
// edge found on a top line
auto* edge2 = found_edges_ply0[i+n_eles_per_dir*2];
ASSERT_EQ(2u, edge2->getNNodes());
ASSERT_EQ(n_nodes_per_dir*n_nodes_per_dir-1-i, edge2->getNodeIndex(0));
ASSERT_EQ(n_nodes_per_dir*n_nodes_per_dir-1-(i+1), edge2->getNodeIndex(1));
// edge found on a left line
auto* edge3 = found_edges_ply0[i+n_eles_per_dir*3];
ASSERT_EQ(2u, edge3->getNNodes());
ASSERT_EQ(n_nodes_per_dir*(n_nodes_per_dir-1)-n_nodes_per_dir*i, edge3->getNodeIndex(0));
ASSERT_EQ(n_nodes_per_dir*(n_nodes_per_dir-1)-n_nodes_per_dir*(i+1), edge3->getNodeIndex(1));
}
std::for_each(pnts.begin(), pnts.end(), [](GeoLib::Point* pnt) { delete pnt; });
}
TEST_F(MeshLibBoundaryElementSearchInSimpleHexMesh, SurfaceSearch)
{
ASSERT_TRUE(_hex_mesh != nullptr);
const std::size_t n_nodes_1d = _number_of_subdivisions_per_direction + 1;
const std::size_t n_nodes_2d = n_nodes_1d * n_nodes_1d;
const std::size_t n_eles_2d = (n_nodes_1d-1) * (n_nodes_1d-1);
// create bottom and front surfaces of a cubic
std::vector<GeoLib::Point*> pnts;
pnts.push_back(new GeoLib::Point(0.0, 0.0, 0.0));
pnts.push_back(new GeoLib::Point(_geometric_size, 0.0, 0.0));
pnts.push_back(new GeoLib::Point(_geometric_size, _geometric_size, 0.0));
pnts.push_back(new GeoLib::Point(0.0, _geometric_size, 0.0));
pnts.push_back(new GeoLib::Point(_geometric_size, 0.0, _geometric_size));
pnts.push_back(new GeoLib::Point(0.0, 0.0, _geometric_size));
GeoLib::Polyline ply_bottom(pnts);
ply_bottom.addPoint(0);
ply_bottom.addPoint(1);
ply_bottom.addPoint(2);
ply_bottom.addPoint(3);
ply_bottom.addPoint(0);
std::unique_ptr<GeoLib::Surface> sfc_bottom(GeoLib::Surface::createSurface(ply_bottom));
GeoLib::Polyline ply_front(pnts);
ply_front.addPoint(0);
ply_front.addPoint(1);
ply_front.addPoint(4);
ply_front.addPoint(5);
ply_front.addPoint(0);
std::unique_ptr<GeoLib::Surface> sfc_front(GeoLib::Surface::createSurface(ply_front));
// perform search on the bottom surface
MeshGeoToolsLib::MeshNodeSearcher mesh_node_searcher(*_hex_mesh);
MeshGeoToolsLib::BoundaryElementsSearcher boundary_element_searcher(*_hex_mesh, mesh_node_searcher);
std::vector<MeshLib::Element*> const& found_faces_sfc_b(boundary_element_searcher.getBoundaryElements(*sfc_bottom));
ASSERT_EQ(n_eles_2d, found_faces_sfc_b.size());
double sum_area_b = std::accumulate(found_faces_sfc_b.begin(), found_faces_sfc_b.end(), 0.0,
[](double v, MeshLib::Element*e){return v+e->getContent();});
ASSERT_EQ(_geometric_size*_geometric_size, sum_area_b);
auto connected_nodeIDs_b = MeshLib::getConnectedNodeIDs(found_faces_sfc_b);
ASSERT_EQ(n_nodes_2d, connected_nodeIDs_b.size());
for (auto nodeID : connected_nodeIDs_b)
ASSERT_EQ(0.0, (*_hex_mesh->getNode(nodeID))[2]); // check z coordinates
// perform search on the front surface
std::vector<MeshLib::Element*> const& found_faces_sfc_f(boundary_element_searcher.getBoundaryElements(*sfc_front));
ASSERT_EQ(n_eles_2d, found_faces_sfc_f.size());
double sum_area_f = std::accumulate(found_faces_sfc_f.begin(), found_faces_sfc_f.end(), 0.0,
[](double v, MeshLib::Element*e){return v+e->getContent();});
ASSERT_EQ(_geometric_size*_geometric_size, sum_area_f);
auto connected_nodeIDs_f = MeshLib::getConnectedNodeIDs(found_faces_sfc_f);
ASSERT_EQ(n_nodes_2d, connected_nodeIDs_f.size());
for (auto nodeID : connected_nodeIDs_f)
ASSERT_EQ(0.0, (*_hex_mesh->getNode(nodeID))[1]); // check y coordinates
std::for_each(pnts.begin(), pnts.end(), [](GeoLib::Point* pnt) { delete pnt; });
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment