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

Merge pull request #454 from norihiro-w/add-gen-distribute

generate node value distribution from ISpatialFunction
parents bb11199e 221dcb04
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,8 @@ SET ( SOURCES ${SOURCES} ${SOURCES_TIMESTEP} ${SOURCES_TIMESTEP_ALGORITHMS}) ...@@ -19,6 +19,8 @@ SET ( SOURCES ${SOURCES} ${SOURCES_TIMESTEP} ${SOURCES_TIMESTEP_ALGORITHMS})
GET_SOURCE_FILES(SOURCES_FUNCTION Function) GET_SOURCE_FILES(SOURCES_FUNCTION Function)
SET ( SOURCES ${SOURCES} ${SOURCES_FUNCTION}) SET ( SOURCES ${SOURCES} ${SOURCES_FUNCTION})
GET_SOURCE_FILES(SOURCES_DISTRIBUTION Distribution)
SET ( SOURCES ${SOURCES} ${SOURCES_DISTRIBUTION})
INCLUDE_DIRECTORIES ( INCLUDE_DIRECTORIES (
......
/**
* \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 "Distribution.h"
#include <algorithm>
#include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "NumLib/Function/ISpatialFunction.h"
namespace NumLib
{
std::vector<double> generateNodeValueDistribution(
const NumLib::ISpatialFunction &func,
const MeshLib::Mesh &msh,
const std::vector<std::size_t> &vec_node_ids)
{
// evaluate a given function with nodal coordinates
std::vector<double> vec_values(vec_node_ids.size());
std::transform(vec_node_ids.begin(), vec_node_ids.end(), vec_values.begin(),
[&func, &msh](std::size_t node_id)
{
return func(*msh.getNode(node_id));
});
return vec_values;
}
} //NumLib
/**
* \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 DISTRIBUTION_H_
#define DISTRIBUTION_H_
#include <vector>
namespace MeshLib
{
class Mesh;
}
namespace NumLib
{
class ISpatialFunction;
/**
* Generate distributed node values from a given function
*
* @param func a spatial function object
* @param msh a mesh object
* @param vec_node_ids a vector of mesh node ids where the function is evaluated
* @return a vector of nodal values
*/
std::vector<double> generateNodeValueDistribution(
const NumLib::ISpatialFunction &func,
const MeshLib::Mesh &msh,
const std::vector<std::size_t> &vec_node_ids);
} // NumLib
#endif // DISTRIBUTION_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 <gtest/gtest.h>
#include <vector>
#include <memory>
#include "GEOObjects.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h"
#include "MeshGeoToolsLib/MeshNodesAlongPolyline.h"
#include "MeshGeoToolsLib/MeshNodesAlongSurface.h"
#include "NumLib/Function/LinearInterpolationAlongPolyline.h"
#include "NumLib/Function/LinearInterpolationOnSurface.h"
#include "NumLib/Function/SpatialFunctionLinear.h"
#include "NumLib/Distribution/Distribution.h"
#include "../TestTools.h"
class NumLibDistributionQuad : public testing::Test
{
public:
NumLibDistributionQuad() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_msh(MeshLib::MeshGenerator::generateRegularQuadMesh(_geometric_size, _number_of_subdivisions_per_direction)),
_project_name("test"), _mshNodesSearcher(*_msh), _ply0(nullptr)
{
// create geometry
std::vector<GeoLib::Point*>* pnts (new std::vector<GeoLib::Point*>);
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));
std::vector<GeoLib::Polyline*>* plys (new std::vector<GeoLib::Polyline*>);
_ply0 = new GeoLib::Polyline(*pnts);
_ply0->addPoint(0);
_ply0->addPoint(1);
plys->push_back(_ply0);
GeoLib::Polyline* ply1 = new GeoLib::Polyline(*pnts);
ply1->addPoint(0);
ply1->addPoint(1);
ply1->addPoint(2);
ply1->addPoint(3);
ply1->addPoint(0);
plys->push_back(ply1);
std::vector<GeoLib::Surface*>* sfcs (new std::vector<GeoLib::Surface*>);
_sfc1 = GeoLib::Surface::createSurface(*ply1);
sfcs->push_back(_sfc1);
_geo_objs.addPointVec(pnts,_project_name);
_geo_objs.addPolylineVec(plys, _project_name);
_geo_objs.addSurfaceVec(sfcs, _project_name);
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
std::unique_ptr<MeshLib::Mesh> _msh;
GeoLib::GEOObjects _geo_objs;
std::string _project_name;
MeshGeoToolsLib::MeshNodeSearcher _mshNodesSearcher;
GeoLib::Polyline* _ply0;
GeoLib::Surface* _sfc1;
};
class NumLibDistributionHex : public testing::Test
{
public:
NumLibDistributionHex() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_msh(MeshLib::MeshGenerator::generateRegularHexMesh(_geometric_size, _number_of_subdivisions_per_direction)),
_project_name("test"), _mshNodesSearcher(*_msh), _ply0(nullptr)
{
// create geometry
std::vector<GeoLib::Point*>* pnts (new std::vector<GeoLib::Point*>);
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(0.0, 0.0, _geometric_size));
pnts->push_back(new GeoLib::Point(_geometric_size, 0.0, _geometric_size));
pnts->push_back(new GeoLib::Point(_geometric_size, _geometric_size, _geometric_size));
pnts->push_back(new GeoLib::Point(0.0, _geometric_size, _geometric_size));
std::vector<GeoLib::Polyline*>* plys (new std::vector<GeoLib::Polyline*>);
_ply0 = new GeoLib::Polyline(*pnts); // vertical polyline
_ply0->addPoint(0);
_ply0->addPoint(4);
plys->push_back(_ply0);
GeoLib::Polyline* ply1 = new GeoLib::Polyline(*pnts); // polygon for left surface
ply1->addPoint(0);
ply1->addPoint(3);
ply1->addPoint(7);
ply1->addPoint(4);
ply1->addPoint(0);
plys->push_back(ply1);
std::vector<GeoLib::Surface*>* sfcs (new std::vector<GeoLib::Surface*>);
_sfc1 = GeoLib::Surface::createSurface(*ply1);
sfcs->push_back(_sfc1);
_geo_objs.addPointVec(pnts,_project_name);
_geo_objs.addPolylineVec(plys, _project_name);
_geo_objs.addSurfaceVec(sfcs, _project_name);
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
std::unique_ptr<MeshLib::Mesh> _msh;
GeoLib::GEOObjects _geo_objs;
std::string _project_name;
MeshGeoToolsLib::MeshNodeSearcher _mshNodesSearcher;
GeoLib::Polyline* _ply0;
GeoLib::Surface* _sfc1;
};
TEST_F(NumLibDistributionQuad, Linear)
{
// f(x,y,z) = 1 + 2x + 3y + 4z
std::array<double,4> f_coeff = {{1, 2, 3, 4}};
MathLib::LinearFunction<double,3> linear_f(f_coeff);
std::vector<double> expected = {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21}};
NumLib::SpatialFunctionLinear f(linear_f);
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(f, *_msh, vec_node_ids);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibDistributionHex, Linear)
{
// f(x,y,z) = 1 + 2x + 3y + 4z
std::array<double,4> f_coeff = {{1, 2, 3, 4}};
MathLib::LinearFunction<double,3> linear_f(f_coeff);
std::vector<double> expected(std::pow(_number_of_subdivisions_per_direction+1, 2));
const double dL = _geometric_size / _number_of_subdivisions_per_direction;
for (std::size_t i=0; i<expected.size(); i++) {
double x = 0;
double y = (i%(_number_of_subdivisions_per_direction+1)) * dL;
double z = (i/(_number_of_subdivisions_per_direction+1)) * dL;
expected[i] = f_coeff[0] + f_coeff[1]*x + f_coeff[2]*y + f_coeff[3]*z;
}
NumLib::SpatialFunctionLinear f(linear_f);
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(f, *_msh, vec_node_ids);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibDistributionQuad, InterpolationPolyline)
{
const std::vector<std::size_t> vec_point_ids = {{0, 1}};
const std::vector<double> vec_point_values = {{0., 100.}};
std::vector<double> expected = {{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}};
NumLib::LinearInterpolationAlongPolyline interpolate(
*_ply0, vec_point_ids, vec_point_values, std::numeric_limits<double>::epsilon(), std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(interpolate, *_msh, vec_node_ids);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibDistributionHex, InterpolationPolyline)
{
const std::vector<std::size_t> vec_point_ids = {{0, 4}};
const std::vector<double> vec_point_values = {{0., 100.}};
std::vector<double> expected = {{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}};
NumLib::LinearInterpolationAlongPolyline interpolate(
*_ply0, vec_point_ids, vec_point_values, std::numeric_limits<double>::epsilon(), std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(interpolate, *_msh, vec_node_ids);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibDistributionQuad, InterpolationSurface)
{
const std::vector<std::size_t> vec_point_ids = {{0, 1, 2, 3}};
const std::vector<double> vec_point_values = {{0., 100., 100., 0.}};
std::vector<double> expected(_msh->getNNodes());
for (std::size_t i=0; i<_msh->getNNodes(); i++) {
expected[i] = (i%(_number_of_subdivisions_per_direction+1)) * 10;
}
NumLib::LinearInterpolationOnSurface interpolate(*_sfc1, vec_point_ids, vec_point_values, std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(interpolate, *_msh, vec_node_ids);
// the machine epsilon for double is too small for this test
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<float>::epsilon());
}
TEST_F(NumLibDistributionHex, InterpolationSurface)
{
const std::vector<std::size_t> vec_point_ids = {{0, 3, 7, 4}};
const std::vector<double> vec_point_values = {{0., 100., 100., 0.}};
std::vector<double> expected(std::pow(_number_of_subdivisions_per_direction+1, 2));
for (std::size_t i=0; i<expected.size(); i++) {
expected[i] = (i%(_number_of_subdivisions_per_direction+1)) * 10;
}
NumLib::LinearInterpolationOnSurface interpolate(*_sfc1, vec_point_ids, vec_point_values, std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs();
std::vector<double> interpolated_values = NumLib::generateNodeValueDistribution(interpolate, *_msh, vec_node_ids);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<float>::epsilon());
}
...@@ -16,239 +16,101 @@ ...@@ -16,239 +16,101 @@
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h" #include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h"
#include "MeshGeoToolsLib/MeshNodesAlongPolyline.h"
#include "MeshGeoToolsLib/MeshNodesAlongSurface.h"
#include "NumLib/Function/LinearInterpolationAlongPolyline.h" #include "NumLib/Function/LinearInterpolationAlongPolyline.h"
#include "NumLib/Function/LinearInterpolationOnSurface.h" #include "NumLib/Function/LinearInterpolationOnSurface.h"
#include "NumLib/Function/SpatialFunctionLinear.h" #include "NumLib/Function/SpatialFunctionLinear.h"
#include "../TestTools.h" #include "../TestTools.h"
class NumLibSpatialFunctionQuad : public testing::Test TEST(NumLib, SpatialFunctionLinear)
{
public:
NumLibSpatialFunctionQuad() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_msh(MeshLib::MeshGenerator::generateRegularQuadMesh(_geometric_size, _number_of_subdivisions_per_direction)),
_project_name("test"), _mshNodesSearcher(*_msh), _ply0(nullptr)
{
// create geometry
std::vector<GeoLib::Point*>* pnts (new std::vector<GeoLib::Point*>);
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));
std::vector<GeoLib::Polyline*>* plys (new std::vector<GeoLib::Polyline*>);
_ply0 = new GeoLib::Polyline(*pnts);
_ply0->addPoint(0);
_ply0->addPoint(1);
plys->push_back(_ply0);
GeoLib::Polyline* ply1 = new GeoLib::Polyline(*pnts);
ply1->addPoint(0);
ply1->addPoint(1);
ply1->addPoint(2);
ply1->addPoint(3);
ply1->addPoint(0);
plys->push_back(ply1);
std::vector<GeoLib::Surface*>* sfcs (new std::vector<GeoLib::Surface*>);
_sfc1 = GeoLib::Surface::createSurface(*ply1);
sfcs->push_back(_sfc1);
_geo_objs.addPointVec(pnts,_project_name);
_geo_objs.addPolylineVec(plys, _project_name);
_geo_objs.addSurfaceVec(sfcs, _project_name);
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
std::unique_ptr<MeshLib::Mesh> _msh;
GeoLib::GEOObjects _geo_objs;
std::string _project_name;
MeshGeoToolsLib::MeshNodeSearcher _mshNodesSearcher;
GeoLib::Polyline* _ply0;
GeoLib::Surface* _sfc1;
};
class NumLibSpatialFunctionHex : public testing::Test
{
public:
NumLibSpatialFunctionHex() :
_geometric_size(10.0), _number_of_subdivisions_per_direction(10),
_msh(MeshLib::MeshGenerator::generateRegularHexMesh(_geometric_size, _number_of_subdivisions_per_direction)),
_project_name("test"), _mshNodesSearcher(*_msh), _ply0(nullptr)
{
// create geometry
std::vector<GeoLib::Point*>* pnts (new std::vector<GeoLib::Point*>);
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(0.0, 0.0, _geometric_size));
pnts->push_back(new GeoLib::Point(_geometric_size, 0.0, _geometric_size));
pnts->push_back(new GeoLib::Point(_geometric_size, _geometric_size, _geometric_size));
pnts->push_back(new GeoLib::Point(0.0, _geometric_size, _geometric_size));
std::vector<GeoLib::Polyline*>* plys (new std::vector<GeoLib::Polyline*>);
_ply0 = new GeoLib::Polyline(*pnts); // vertical polyline
_ply0->addPoint(0);
_ply0->addPoint(4);
plys->push_back(_ply0);
GeoLib::Polyline* ply1 = new GeoLib::Polyline(*pnts); // polygon for left surface
ply1->addPoint(0);
ply1->addPoint(3);
ply1->addPoint(7);
ply1->addPoint(4);
ply1->addPoint(0);
plys->push_back(ply1);
std::vector<GeoLib::Surface*>* sfcs (new std::vector<GeoLib::Surface*>);
_sfc1 = GeoLib::Surface::createSurface(*ply1);
sfcs->push_back(_sfc1);
_geo_objs.addPointVec(pnts,_project_name);
_geo_objs.addPolylineVec(plys, _project_name);
_geo_objs.addSurfaceVec(sfcs, _project_name);
}
protected:
const double _geometric_size;
const std::size_t _number_of_subdivisions_per_direction;
std::unique_ptr<MeshLib::Mesh> _msh;
GeoLib::GEOObjects _geo_objs;
std::string _project_name;
MeshGeoToolsLib::MeshNodeSearcher _mshNodesSearcher;
GeoLib::Polyline* _ply0;
GeoLib::Surface* _sfc1;
};
template <class T_TASK>
class NodeIDtoNodeObject
{
public:
NodeIDtoNodeObject(const MeshLib::Mesh& msh, const T_TASK& task)
: _msh(msh), _task(task) {}
double operator()(std::size_t node_id)
{
return _task(*_msh.getNode(node_id));
}
private:
const MeshLib::Mesh& _msh;
const T_TASK& _task;
};
TEST_F(NumLibSpatialFunctionQuad, Linear)
{ {
// f(x,y,z) = 1 + 2x + 3y + 4z // f(x,y,z) = 1 + 2x + 3y + 4z
std::array<double,4> f_coeff = {{1, 2, 3, 4}}; std::array<double,4> f_coeff = {{1, 2, 3, 4}};
MathLib::LinearFunction<double,3> linear_f(f_coeff); MathLib::LinearFunction<double,3> linear_f(f_coeff);
std::vector<double> expected = {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21}};
NumLib::SpatialFunctionLinear f(linear_f); NumLib::SpatialFunctionLinear f(linear_f);
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values(vec_node_ids.size());
NodeIDtoNodeObject<NumLib::SpatialFunctionLinear> task(*_msh, f);
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibSpatialFunctionHex, Linear) ASSERT_DOUBLE_EQ(1., f(GeoLib::Point(0,0,0)));
{ ASSERT_DOUBLE_EQ(10., f(GeoLib::Point(1,1,1)));
// f(x,y,z) = 1 + 2x + 3y + 4z ASSERT_DOUBLE_EQ(-8, f(GeoLib::Point(-1,-1,-1)));
std::array<double,4> f_coeff = {{1, 2, 3, 4}}; for (std::size_t k(0); k < 5; ++k)
MathLib::LinearFunction<double,3> linear_f(f_coeff); {
std::vector<double> expected(std::pow(_number_of_subdivisions_per_direction+1, 2)); GeoLib::Point pt(0, 0, 0);
const double dL = _geometric_size / _number_of_subdivisions_per_direction; for (unsigned i = 0; i < 3; ++i)
for (std::size_t i=0; i<expected.size(); i++) { pt[i] = (double) rand() - (RAND_MAX / 2.0);
double x = 0; double expected = 1+2*pt[0]+3*pt[1]+4*pt[2];
double y = (i%(_number_of_subdivisions_per_direction+1)) * dL; ASSERT_DOUBLE_EQ(expected, f(pt));
double z = (i/(_number_of_subdivisions_per_direction+1)) * dL;
expected[i] = f_coeff[0] + f_coeff[1]*x + f_coeff[2]*y + f_coeff[3]*z;
} }
NumLib::SpatialFunctionLinear f(linear_f);
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs();
std::vector<double> interpolated_values(vec_node_ids.size());
NodeIDtoNodeObject<NumLib::SpatialFunctionLinear> task(*_msh, f);
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
} }
TEST_F(NumLibSpatialFunctionQuad, InterpolationPolyline) TEST(NumLib, SpatialFunctionInterpolationPolyline)
{ {
// create geometry
GeoLib::Point pt1(0.0, 0.0, 0.0);
GeoLib::Point pt2(10.0, 0.0, 0.0);
std::vector<GeoLib::Point*> pnts = {&pt1, &pt2};
GeoLib::Polyline ply0(pnts);
ply0.addPoint(0);
ply0.addPoint(1);
// define a function
const std::vector<std::size_t> vec_point_ids = {{0, 1}}; const std::vector<std::size_t> vec_point_ids = {{0, 1}};
const std::vector<double> vec_point_values = {{0., 100.}}; const std::vector<double> vec_point_values = {{0., 100.}};
std::vector<double> expected = {{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}};
NumLib::LinearInterpolationAlongPolyline interpolate(
*_ply0, vec_point_ids, vec_point_values, std::numeric_limits<double>::epsilon(), std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values(vec_node_ids.size());
NodeIDtoNodeObject<NumLib::LinearInterpolationAlongPolyline> task(*_msh, interpolate);
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task);
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon());
}
TEST_F(NumLibSpatialFunctionHex, InterpolationPolyline)
{
const std::vector<std::size_t> vec_point_ids = {{0, 4}};
const std::vector<double> vec_point_values = {{0., 100.}};
std::vector<double> expected = {{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}};
NumLib::LinearInterpolationAlongPolyline interpolate( NumLib::LinearInterpolationAlongPolyline interpolate(
*_ply0, vec_point_ids, vec_point_values, std::numeric_limits<double>::epsilon(), std::numeric_limits<double>::max()); ply0, vec_point_ids, vec_point_values, std::numeric_limits<double>::epsilon(), std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongPolyline(*_ply0).getNodeIDs();
std::vector<double> interpolated_values(vec_node_ids.size()); // normal
NodeIDtoNodeObject<NumLib::LinearInterpolationAlongPolyline> task(*_msh, interpolate); for (unsigned k=0; k<10; k++)
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task); ASSERT_DOUBLE_EQ(k*10., interpolate(GeoLib::Point(k,0,0)));
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<double>::epsilon()); // failure
// x
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(-1,0,0)));
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(11,0,0)));
// y
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,1,0)));
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,-1,0)));
// z
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,0,1)));
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,0,-1)));
} }
TEST_F(NumLibSpatialFunctionQuad, InterpolationSurface) TEST(NumLib, SpatialFunctionInterpolationSurface)
{ {
// create geometry
GeoLib::Point pt1(0.0, 0.0, 0.0);
GeoLib::Point pt2(10.0, 0.0, 0.0);
GeoLib::Point pt3(10.0, 10.0, 0.0);
GeoLib::Point pt4(0.0, 10.0, 0.0);
std::vector<GeoLib::Point*> pnts = {&pt1, &pt2, &pt3, &pt4};
GeoLib::Polyline ply0(pnts);
ply0.addPoint(0);
ply0.addPoint(1);
ply0.addPoint(2);
ply0.addPoint(3);
ply0.addPoint(0);
std::unique_ptr<GeoLib::Surface> sfc1(GeoLib::Surface::createSurface(ply0));
// define a function
const std::vector<std::size_t> vec_point_ids = {{0, 1, 2, 3}}; const std::vector<std::size_t> vec_point_ids = {{0, 1, 2, 3}};
const std::vector<double> vec_point_values = {{0., 100., 100., 0.}}; const std::vector<double> vec_point_values = {{0., 100., 100., 0.}};
std::vector<double> expected(_msh->getNNodes()); NumLib::LinearInterpolationOnSurface interpolate(*sfc1, vec_point_ids, vec_point_values, std::numeric_limits<double>::max());
for (std::size_t i=0; i<_msh->getNNodes(); i++) {
expected[i] = (i%(_number_of_subdivisions_per_direction+1)) * 10;
}
NumLib::LinearInterpolationOnSurface interpolate(*_sfc1, vec_point_ids, vec_point_values, std::numeric_limits<double>::max());
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs();
std::vector<double> interpolated_values(vec_node_ids.size());
NodeIDtoNodeObject<NumLib::LinearInterpolationOnSurface> task(*_msh, interpolate);
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task);
// the machine epsilon for double is too small for this test
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<float>::epsilon());
}
TEST_F(NumLibSpatialFunctionHex, InterpolationSurface) // normal
{ for (unsigned k=0; k<10; k++) {
const std::vector<std::size_t> vec_point_ids = {{0, 3, 7, 4}}; ASSERT_DOUBLE_EQ(k*10., interpolate(GeoLib::Point(k,0,0)));
const std::vector<double> vec_point_values = {{0., 100., 100., 0.}}; ASSERT_DOUBLE_EQ(k*10., interpolate(GeoLib::Point(k,5,0)));
std::vector<double> expected(std::pow(_number_of_subdivisions_per_direction+1, 2)); ASSERT_DOUBLE_EQ(k*10., interpolate(GeoLib::Point(k,10,0)));
for (std::size_t i=0; i<expected.size(); i++) {
expected[i] = (i%(_number_of_subdivisions_per_direction+1)) * 10;
} }
NumLib::LinearInterpolationOnSurface interpolate(*_sfc1, vec_point_ids, vec_point_values, std::numeric_limits<double>::max()); // failure
const std::vector<std::size_t>& vec_node_ids = _mshNodesSearcher.getMeshNodesAlongSurface(*_sfc1).getNodeIDs(); // x, y
std::vector<double> interpolated_values(vec_node_ids.size()); ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(-1,-1,0)));
NodeIDtoNodeObject<NumLib::LinearInterpolationOnSurface> task(*_msh, interpolate); ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(11,-1,0)));
std::transform(vec_node_ids.begin(), vec_node_ids.end(), interpolated_values.begin(), task); ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(11,11,0)));
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(-1,11,0)));
ASSERT_ARRAY_NEAR(expected, interpolated_values, expected.size(), std::numeric_limits<float>::epsilon()); // z
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,0,1)));
ASSERT_DOUBLE_EQ(std::numeric_limits<double>::max(), interpolate(GeoLib::Point(0,0,-1)));
} }
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