Skip to content

Commit

Permalink
[Mapping.NonLinear] Add tests for DistanceMultiMapping (#5077)
Browse files Browse the repository at this point in the history
* [Mapping.NonLinear] Add tests for DistanceMultiMapping

* clearer expected output
  • Loading branch information
alxbilger authored Nov 7, 2024
1 parent ea7f52a commit 679a914
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ void DistanceMapping<TIn, TOut>::init()
l_topology.set(this->getContext()->getMeshTopologyLink());
}

if (!l_topology)
{
msg_error() << "No topology found";
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'";

if (l_topology->getNbEdges() < 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace sofa::component::mapping::nonlinear
* @author Matthieu Nesme
*/
template <class TIn, class TOut>
class DistanceMultiMapping : public core::MultiMapping<TIn, TOut>, public NonLinearMappingData<true>
class DistanceMultiMapping : public core::MultiMapping<TIn, TOut>, public StabilizedNonLinearMappingData
{
public:
SOFA_CLASS(SOFA_TEMPLATE2(DistanceMultiMapping,TIn,TOut), SOFA_TEMPLATE2(core::MultiMapping,TIn,TOut));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,19 @@ void DistanceMultiMapping<TIn, TOut>::init()
l_topology.set(this->getContext()->getMeshTopologyLink());
}

if (!l_topology)
{
msg_error() << "No topology found";
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

msg_info() << "Topology path used: '" << l_topology.getLinkedPath() << "'";

if (l_topology->getNbEdges() < 1)
{
msg_error() << "No Topology component containing edges found at path: " << l_topology.getLinkedPath() << ", nor in current context: " << this->getContext()->name;
sofa::core::objectmodel::BaseObject::d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
return;
}

Expand All @@ -103,22 +110,28 @@ void DistanceMultiMapping<TIn, TOut>::init()
// compute the rest lengths if they are not known
if(d_restLengths.getValue().size() != links.size() )
{
helper::WriteAccessor< Data<type::vector<Real> > > restLengths(d_restLengths);
restLengths.resize( links.size() );
if(!(d_computeDistance.getValue()))
helper::WriteAccessor restLengths(d_restLengths);
restLengths->clear();
restLengths->reserve( links.size() );
if(!d_computeDistance.getValue())
{
for(unsigned i=0; i<links.size(); i++ )
for (const auto& edge : links)
{
const type::Vec2i& pair0 = pairs[ links[i][0] ];
const type::Vec2i& pair1 = pairs[ links[i][1] ];
const auto& [e0, e1] = edge.array();

assert(e0 < pairs.size());
assert(e1 < pairs.size());

const type::Vec2i& pair0 = pairs[ e0 ];
const type::Vec2i& pair1 = pairs[ e1 ];

auto posPair0 = this->getFromModels()[pair0[0]]->readPositions();
auto posPair1 = this->getFromModels()[pair1[0]]->readPositions();

const InCoord& pos0 = posPair0[pair0[1]];
const InCoord& pos1 = posPair1[pair1[1]];

restLengths[i] = (pos0 - pos1).norm();
restLengths->emplace_back((pos0 - pos1).norm());
}
}
else
Expand Down
1 change: 1 addition & 0 deletions Sofa/Component/Mapping/NonLinear/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project(Sofa.Component.Mapping.NonLinear_test)
set(SOURCE_FILES
AreaMapping_test.cpp
DistanceMapping_test.cpp
DistanceMultiMapping_test.cpp
RigidMapping_test.cpp
SquareDistanceMapping_test.cpp
SquareMapping_test.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture *
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#include <sofa/component/mapping/nonlinear/DistanceMultiMapping.h>
#include <sofa/component/mapping/testing/MultiMappingTestCreation.h>
#include <sofa/component/topology/container/dynamic/EdgeSetTopologyContainer.h>

namespace sofa
{
template <typename _DistanceMultiMapping>
struct DistanceMultiMappingTest : public MultiMapping_test<_DistanceMultiMapping>
{
using In = typename _DistanceMultiMapping::In;
using Out = typename _DistanceMultiMapping::Out;

bool test(bool computeDistance)
{
constexpr int numberOfParents = 2;
this->setupScene(numberOfParents); // NP parents, 1 child

_DistanceMultiMapping* map = static_cast<_DistanceMultiMapping*>( this->mapping );
EXPECT_NE(map, nullptr);

map->d_indexPairs.setValue({{0, 0}, {1, 0}});
sofa::helper::getWriteAccessor(map->d_geometricStiffness)->setSelectedItem(1);
map->d_computeDistance.setValue(computeDistance);

const component::topology::container::dynamic::EdgeSetTopologyContainer::SPtr edges = sofa::core::objectmodel::New<component::topology::container::dynamic::EdgeSetTopologyContainer>();
this->root->addObject(edges);
edges->addEdge( 0, 1 );

// parent positions
sofa::type::vector< VecCoord_t<In> > incoords(numberOfParents);
for (auto& in : incoords)
{
in.resize(1);
}

In::set( incoords[0][0], 1, 2, 3);
In::set( incoords[1][0], 4, 1, 5);

VecCoord_t<Out> outcoords(1);
if (computeDistance)
{
const auto expectedDistance = (In::getCPos(incoords[1][0]) - In::getCPos(incoords[0][0])).norm();
Out::set( outcoords[0], expectedDistance, 0.,0.);
}
else
{
Out::set( outcoords[0], 0,0,0);
}
return this->runTest(incoords,outcoords);
}
};

using ::testing::Types;
typedef Types<
sofa::component::mapping::nonlinear::DistanceMultiMapping<defaulttype::Vec3Types,defaulttype::Vec1Types>,
sofa::component::mapping::nonlinear::DistanceMultiMapping<defaulttype::Rigid3Types,defaulttype::Vec1Types>
> DataTypes;


TYPED_TEST_SUITE(DistanceMultiMappingTest, DataTypes);

TYPED_TEST( DistanceMultiMappingTest, computeDistance )
{
this->errorMax = 1000;
ASSERT_TRUE(this->test(true));
}

TYPED_TEST( DistanceMultiMappingTest, notComputeDistance )
{
this->errorMax = 1000;
ASSERT_TRUE(this->test(false));
}

}

0 comments on commit 679a914

Please sign in to comment.