https://gitlab.opengeosys.org/ogs/ogs.git
Tip revision: 33722ed3caadb3b85137763605036862dc33d823 authored by Dmitri Naumov on 21 September 2021, 21:49:22 UTC
[T/partmesh] Update config files references.
[T/partmesh] Update config files references.
Tip revision: 33722ed
Parameter.cpp
/**
* \copyright
* Copyright (c) 2012-2021, 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 <boost/property_tree/xml_parser.hpp>
#include <numeric>
#include <sstream>
#include <vector>
#include "BaseLib/ConfigTree.h"
#include "BaseLib/Logging.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshLib/Node.h"
#include "MeshLib/PropertyVector.h"
#include "ParameterLib/CurveScaledParameter.h"
#include "ParameterLib/GroupBasedParameter.h"
#include "Tests/TestTools.h"
using namespace ParameterLib;
std::unique_ptr<Parameter<double>> constructParameterFromString(
std::string const& xml,
std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
std::map<std::string,
std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
curves = {})
{
auto const xml_ptree = Tests::readXml(xml.c_str());
BaseLib::ConfigTree config_tree(xml_ptree, "", BaseLib::ConfigTree::onerror,
BaseLib::ConfigTree::onwarning);
auto parameter_base = createParameter(config_tree, meshes, curves);
return std::unique_ptr<Parameter<double>>(
static_cast<Parameter<double>*>(parameter_base.release()));
}
struct ParameterLibParameter : public ::testing::Test
{
void SetUp() override
{
// A mesh with four elements, five points.
meshes.emplace_back(MeshLib::MeshGenerator::generateLineMesh(4u, 1.0));
}
std::vector<std::unique_ptr<MeshLib::Mesh>> meshes;
};
TEST_F(ParameterLibParameter, GroupBasedParameterElement)
{
std::vector<int> mat_ids({0, 1, 2, 3});
MeshLib::addPropertyToMesh(*meshes[0], "MaterialIDs",
MeshLib::MeshItemType::Cell, 1, mat_ids);
auto parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>Group</type>"
"<group_id_property>MaterialIDs</group_id_property>"
"<index_values><index>0</index><value>0</value></index_values>"
"<index_values><index>1</index><value>100</value></index_values>"
"<index_values><index>3</index><value>300</value></index_values>",
meshes);
double t = 0;
ParameterLib::SpatialPosition x;
x.setElementID(0);
ASSERT_EQ(0.0, (*parameter)(t, x)[0]);
x.setElementID(1);
ASSERT_EQ(100.0, (*parameter)(t, x)[0]);
x.setElementID(2);
ASSERT_ANY_THROW((*parameter)(t, x));
x.setElementID(3);
ASSERT_EQ(300.0, (*parameter)(t, x)[0]);
}
TEST_F(ParameterLibParameter, GroupBasedParameterNode)
{
std::vector<int> group_ids({0, 1, 2, 3, 4});
MeshLib::addPropertyToMesh(*meshes[0], "PointGroupIDs",
MeshLib::MeshItemType::Node, 1, group_ids);
auto parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>Group</type>"
"<group_id_property>PointGroupIDs</group_id_property>"
"<index_values><index>0</index><value>0</value></index_values>"
"<index_values><index>1</index><value>100</value></index_values>"
"<index_values><index>3</index><value>300</value></index_values>",
meshes);
double t = 0;
ParameterLib::SpatialPosition x;
x.setNodeID(0);
ASSERT_EQ(0.0, (*parameter)(t, x)[0]);
x.setNodeID(1);
ASSERT_EQ(100.0, (*parameter)(t, x)[0]);
x.setNodeID(2);
ASSERT_ANY_THROW((*parameter)(t, x));
x.setNodeID(3);
ASSERT_EQ(300.0, (*parameter)(t, x)[0]);
x.setNodeID(4);
ASSERT_ANY_THROW((*parameter)(t, x));
}
bool testNodalValuesOfElement(
std::vector<MeshLib::Element*> const& elements,
std::function<double(MeshLib::Element* const e,
std::size_t const local_node_id)>
get_expected_value,
Parameter<double> const& parameter,
double const t)
{
return std::all_of(
begin(elements), end(elements), [&](MeshLib::Element* const e) {
// scalar values, 2 nodes.
Eigen::Matrix<double, 2, 1> const nodal_values =
parameter.getNodalValuesOnElement(*e, t);
if (nodal_values.cols() != 1)
{
ERR("Expected scalar nodal values.");
return false;
}
if (nodal_values.rows() != static_cast<int>(e->getNumberOfNodes()))
{
ERR("Expected equal number of element nodes and the nodal "
"values.");
return false;
}
for (std::size_t i = 0; i < e->getNumberOfNodes(); ++i)
{
double const expected_value = get_expected_value(e, i);
if (expected_value != nodal_values(i, 0))
{
ERR("Mismatch for element {:d}, node {:d}; Expected {:g}, "
"got {:g}.",
e->getID(), i, expected_value, nodal_values(i, 0));
return false;
}
}
return true;
});
}
// For all elements all nodes have a constant value.
TEST_F(ParameterLibParameter, GetNodalValuesOnElement_constant)
{
auto const parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>Constant</type>"
"<value>42.23</value>",
meshes);
double const t = 0;
auto expected_value = [](MeshLib::Element* const /*e*/,
std::size_t const /*local_node_id*/) {
return 42.23;
};
ASSERT_TRUE(testNodalValuesOfElement(meshes[0]->getElements(),
expected_value, *parameter, t));
}
TEST_F(ParameterLibParameter, GetNodalValuesOnElement_node)
{
std::vector<double> node_ids({0, 1, 2, 3, 4});
MeshLib::addPropertyToMesh(*meshes[0], "NodeIDs",
MeshLib::MeshItemType::Node, 1, node_ids);
auto const parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>MeshNode</type>"
"<field_name>NodeIDs</field_name>",
meshes);
double const t = 0;
// For all elements all nodes have the value of the node id.
auto expected_value = [](MeshLib::Element* const e,
std::size_t const local_node_id) {
return static_cast<double>(e->getNode(local_node_id)->getID());
};
ASSERT_TRUE(testNodalValuesOfElement(meshes[0]->getElements(),
expected_value, *parameter, t));
}
TEST_F(ParameterLibParameter, GetNodalValuesOnElement_element)
{
std::vector<double> element_ids({0, 1, 2, 3});
MeshLib::addPropertyToMesh(*meshes[0], "ElementIDs",
MeshLib::MeshItemType::Cell, 1, element_ids);
auto const parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>MeshElement</type>"
"<field_name>ElementIDs</field_name>",
meshes);
double const t = 0;
// For all elements all nodes have the value of the element id.
auto expected_value = [](MeshLib::Element* const e,
std::size_t const /*local_node_id*/) {
return static_cast<double>(e->getID());
};
ASSERT_TRUE(testNodalValuesOfElement(meshes[0]->getElements(),
expected_value, *parameter, t));
}
TEST_F(ParameterLibParameter, GetNodalValuesOnElement_curveScaledNode)
{
std::vector<double> node_ids({0, 1, 2, 3, 4});
MeshLib::addPropertyToMesh(*meshes[0], "NodeIDs",
MeshLib::MeshItemType::Node, 1, node_ids);
std::vector<std::unique_ptr<ParameterBase>> parameters;
parameters.emplace_back(
constructParameterFromString("<name>NodeIDs</name>"
"<type>MeshNode</type>"
"<field_name>NodeIDs</field_name>",
meshes));
std::map<std::string,
std::unique_ptr<MathLib::PiecewiseLinearInterpolation>>
curves;
curves["linear_curve"] =
std::make_unique<MathLib::PiecewiseLinearInterpolation>(
std::vector<double>{0, 1}, std::vector<double>{0, 1}, true);
auto const parameter = constructParameterFromString(
"<name>parameter</name>"
"<type>CurveScaled</type>"
"<curve>linear_curve</curve>"
"<parameter>NodeIDs</parameter>",
meshes, curves);
parameter->initialize(parameters);
double const t = 0.5;
// For all elements all nodes have the value of the node id times the time.
auto expected_value = [&t](MeshLib::Element* const e,
std::size_t const local_node_id) {
return static_cast<double>(e->getNode(local_node_id)->getID()) * t;
};
ASSERT_TRUE(testNodalValuesOfElement(meshes[0]->getElements(),
expected_value, *parameter, t));
}