SOFA API  5448a14f
Open source framework for multi-physics simuation
sofa::mapping_test::Mapping_test< _Mapping > Struct Template Reference

#include <MappingTestCreation.h>

Base class for the Mapping tests, with helpers to automatically test applyJ, applyJT, applyDJT and getJs using finite differences. More...

Inheritance diagram for sofa::mapping_test::Mapping_test< _Mapping >:

Detailed Description

template<class _Mapping>
struct sofa::mapping_test::Mapping_test< _Mapping >

Base class for the Mapping tests, with helpers to automatically test applyJ, applyJT, applyDJT and getJs using finite differences.

Specific test cases can be created using a derived class instantiated on the mapping class to test, and calling function runTest( const VecCoord_t<In>& parentInit, const VecCoord_t<Out>& childInit, const VecCoord_t<In> parentNew, const VecCoord_t<Out> expectedChildNew);

This function compares the actual output positions with the expected ones, then automatically tests the methods related to the Jacobian using finite differences.

  • A small change of the input positions dxIn is randomly chosen and added to the current position. The same is set as velocity.
  • mapping->apply is called, and the difference dXout between the new output positions and the previous positions is computed
  • to validate mapping->applyJ, dXin is converted to input velocity vIn and mapping->applyJ is called. dXout and the output velocity vOut must be the same (up to linear approximations errors, thus we apply a very small change of position).
  • to validate mapping->getJs, we use it to get the Jacobian, then we check that J.vIn = vOut
  • to validate mapping->applyJT, we apply it after setting the child force fc=vOut, then we check that parent force fp = J^T.fc
  • to validate mapping->applyDJT, we set the child force, and we compare the parent force before and after a small displacement

The magnitude of the small random changes applied in finite differences is between deltaRange.first*epsilon and deltaRange.second*epsilon, and a failure is issued if the error is greater than errorMax*epsilon, where epsilon=std::numeric_limits<Real>::epsilon() is 1.19209e-07 for float and 2.22045e-16 for double.

Author
François Faure
Date
2013

Public Attributes

core::Mapping< In, Out > * mapping
 the mapping to be tested More...
 
InDOFs::SPtr inDofs
 mapping input More...
 
OutDOFs::SPtr outDofs
 mapping output More...
 
simulation::Node::SPtr root
 Root of the scene graph, created by the constructor an re-used in the tests. More...
 
std::pair< Real_t< In >, Real_t< In > > deltaRange
 The minimum and maximum magnitudes of the change of each scalar value of the small displacement is perturbation * numeric_limits<Real>::epsilon. This epsilon is 1.19209e-07 for float and 2.22045e-16 for double. More...
 
Real_t< InerrorMax
 The test is successful if the (infinite norm of the) difference is less than errorMax * numeric_limits<Real>::epsilon. More...
 
Real_t< InerrorFactorDJ
 The test for geometric stiffness is successful if the (infinite norm of the) difference is less than errorFactorDJ * errorMax * numeric_limits<Real>::epsilon. More...
 
unsigned char flags
 testing options. (all by default). To be used with precaution. Please implement the missing API in the mapping rather than not testing it. More...
 
- Public Attributes inherited from sofa::testing::BaseTest
sofa::testing::MessageAsTestFailure m_fatal
 
sofa::testing::MessageAsTestFailure m_error
 

Static Public Attributes

static constexpr unsigned char TEST_getJs = 1
 testing getJs used in assembly API More...
 
static constexpr unsigned char TEST_getK = 2
 testing getK used in assembly API More...
 
static constexpr unsigned char TEST_applyJT_matrix = 4
 testing applyJT on matrices More...
 
static constexpr unsigned char TEST_applyDJT = 8
 testing applyDJT More...
 
static constexpr unsigned char TEST_buildGeometricStiffnessMatrix = 16
 testing buildGeometricStiffnessMatrix More...
 
static constexpr unsigned char TEST_ASSEMBLY_API = TEST_getJs | TEST_getK
 testing functions used in assembly API getJS getKS More...
 
static constexpr unsigned char TEST_GEOMETRIC_STIFFNESS = TEST_applyDJT | TEST_getK | TEST_buildGeometricStiffnessMatrix
 testing functions used in assembly API getJS getKS More...
 
- Static Public Attributes inherited from sofa::testing::BaseTest
static int seed = (unsigned int)time(nullptr)
 Seed value. More...
 

Public Member Functions

bool isTestExecuted (const unsigned char testFlag) const
 Returns true if the test of the method corresponding to the flag parameter must be executed, false otherwise. More...
 
void setTestExecution (const unsigned char testFlag, const bool doTheTest)
 Defines if a test of the method corresponding to the flag parameter must be executed or not. More...
 
 Mapping_test ()
 
 Mapping_test (std::string fileName)
 
virtual bool runTest (const VecCoord_t< In > &parentInit, const VecCoord_t< Out > &childInit, const VecCoord_t< In > &parentNew, const VecCoord_t< Out > &expectedChildNew)
 
virtual bool runTest (const VecCoord_t< In > &parent, const VecCoord_t< Out > expectedChild)
 
 ~Mapping_test () override
 
- Public Member Functions inherited from sofa::testing::BaseSimulationTest
 BaseSimulationTest ()
 
bool importPlugin (const std::string &name)
 
- Public Member Functions inherited from sofa::testing::BaseTest
 BaseTest ()
 Initialize Sofa and the random number generator. More...
 
 ~BaseTest () override
 
virtual void doSetUp ()
 
virtual void doTearDown ()
 
virtual void onSetUp ()
 
virtual void onTearDown ()
 
void loadPlugins (const std::initializer_list< std::string > &pluginNames)
 
- Public Member Functions inherited from sofa::testing::NumericTest< _Mapping::In::Real >
 NumericTest ()
 
Real vectorMaxDiff (const Container1 &c1, const Container2 &c2)
 Return the maximum difference between two containers. Issues a failure if sizes are different. More...
 
Real vectorMaxAbs (const Container &c)
 Return the maximum absolute value of a container. More...
 

Protected Member Functions

virtual Deriv_t< Outdifference (const Coord_t< Out > &a, const Coord_t< Out > &b)
 
virtual VecDeriv_t< Outdifference (const VecDeriv_t< Out > &a, const VecDeriv_t< Out > &b)
 
virtual VecDeriv_t< OutpreTreatment (const VecDeriv_t< Out > &f)
 
void checkComparisonThreshold ()
 
void warnMissingTests () const
 
bool testMappingPositionVelocity (const VecCoord_t< In > &parentInit, const VecCoord_t< Out > &childInit, const VecCoord_t< In > &parentNew, const VecCoord_t< Out > &expectedChildNew, const Real_t< In > errorThreshold, core::MechanicalParams mparams)
 
template<class DataTypes >
VecDeriv_t< DataTypesgenerateRandomVecDeriv (const std::size_t size, const Real_t< DataTypes > minMagnitude, const Real_t< DataTypes > maxMagnitude)
 
void computeForceInFromForceOut (core::MechanicalParams mparams, VecDeriv_t< In > &forceIn, const VecDeriv_t< Out > &forceOut)
 
void computeVelocityOutFromVelocityIn (core::MechanicalParams mparams, VecDeriv_t< Out > &velocityOut, const VecDeriv_t< In > &velocityIn)
 
const VecDeriv_t< In > & applyDJT (core::MechanicalParams mparams, bool updateK)
 
bool checkApplyDJT (const VecDeriv_t< In > &dfp, const VecDeriv_t< In > &fp12, Real_t< In > errorThreshold, bool updateK)
 
VecCoord_t< IncomputePerturbedPositions (const std::size_t sizeIn, const VecDeriv_t< In > velocityIn)
 
bool checkJacobianMatrixTranspose (EigenSparseMatrix *jacobianMatrix, const VecDeriv_t< Out > &forceOut, const VecDeriv_t< In > &expectedForceIn, Real_t< In > errorThreshold)
 
bool checkJacobianMatrix (EigenSparseMatrix *jacobianMatrix, const VecDeriv_t< In > &velocityIn, const VecDeriv_t< Out > &expectedVelocityOut, Real_t< In > errorThreshold)
 
bool testApplyJonPosition (core::MechanicalParams mparams, const VecCoord_t< Out > &positionOut, const VecDeriv_t< Out > &expectedVelocityOut, Real_t< In > errorThreshold)
 
VecDeriv_t< IncomputeForceChange (core::MechanicalParams mparams, const std::size_t sizeIn, VecDeriv_t< Out > forceOut, VecDeriv_t< In > forceIn)
 
bool testGetK (const std::size_t &sizeIn, const VecDeriv_t< In > &velocityIn, const VecDeriv_t< In > &forceChange, Real_t< In > errorThreshold)
 
bool testBuildGeometricStiffnessMatrix (std::size_t sizeIn, const VecDeriv_t< In > &velocityIn, const VecDeriv_t< In > &forceChange, Real_t< In > errorThreshold)
 

Static Protected Member Functions

template<class EigenSparseMatrixType >
static EigenSparseMatrixType * getMatrix (const type::vector< sofa::linearalgebra::BaseMatrix * > *matrices)
 Get one EigenSparseMatrix out of a list. Error if not one single matrix in the list. More...
 
- Static Protected Member Functions inherited from sofa::testing::NumericTest< _Mapping::In::Real >
static float norm (float a)
 
static double norm (double a)
 
static Real norm (T a)
 

Additional Inherited Members

- Static Public Member Functions inherited from sofa::testing::NumericTest< _Mapping::In::Real >
static Real matrixMaxDiff (const Matrix1 &m1, const Matrix2 &m2)
 return the maximum difference between corresponding entries, or the infinity if the matrices have different sizes More...
 
static Real matrixMaxDiff (const sofa::type::Mat< M, N, Real > &m1, const Matrix2 &m2)
 Return the maximum difference between corresponding entries, or the infinity if the matrices have different sizes. More...
 
static Real epsilon ()
 the smallest real number More...
 
static Real infinity ()
 Infinity. More...
 
static bool isSmall (Real r, Real ratio=1.)
 true if the magnitude of r is less than ratio*epsilon More...
 
static Real vectorMaxDiff (const sofa::type::Vec< N, Real > &m1, const Vector2 &m2)
 return the maximum difference between corresponding entries, or the infinity if the vectors have different sizes More...
 
static Real vectorMaxDiff (const sofa::type::Vec< N, Real > &m1, const sofa::type::Vec< N, Real > &m2)
 return the maximum difference between corresponding entries More...
 

Attribute details

◆ deltaRange

template<class _Mapping >
std::pair<Real_t<In>, Real_t<In> > sofa::mapping_test::Mapping_test< _Mapping >::deltaRange

The minimum and maximum magnitudes of the change of each scalar value of the small displacement is perturbation * numeric_limits<Real>::epsilon. This epsilon is 1.19209e-07 for float and 2.22045e-16 for double.

◆ errorFactorDJ

template<class _Mapping >
Real_t<In> sofa::mapping_test::Mapping_test< _Mapping >::errorFactorDJ

The test for geometric stiffness is successful if the (infinite norm of the) difference is less than errorFactorDJ * errorMax * numeric_limits<Real>::epsilon.

◆ errorMax

template<class _Mapping >
Real_t<In> sofa::mapping_test::Mapping_test< _Mapping >::errorMax

The test is successful if the (infinite norm of the) difference is less than errorMax * numeric_limits<Real>::epsilon.

◆ flags

template<class _Mapping >
unsigned char sofa::mapping_test::Mapping_test< _Mapping >::flags

testing options. (all by default). To be used with precaution. Please implement the missing API in the mapping rather than not testing it.

◆ inDofs

template<class _Mapping >
InDOFs::SPtr sofa::mapping_test::Mapping_test< _Mapping >::inDofs

mapping input

◆ mapping

template<class _Mapping >
core::Mapping<In,Out>* sofa::mapping_test::Mapping_test< _Mapping >::mapping

the mapping to be tested

◆ outDofs

template<class _Mapping >
OutDOFs::SPtr sofa::mapping_test::Mapping_test< _Mapping >::outDofs

mapping output

◆ root

template<class _Mapping >
simulation::Node::SPtr sofa::mapping_test::Mapping_test< _Mapping >::root

Root of the scene graph, created by the constructor an re-used in the tests.

◆ TEST_applyDJT

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_applyDJT = 8
staticconstexpr

testing applyDJT

◆ TEST_applyJT_matrix

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_applyJT_matrix = 4
staticconstexpr

testing applyJT on matrices

◆ TEST_ASSEMBLY_API

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_ASSEMBLY_API = TEST_getJs | TEST_getK
staticconstexpr

testing functions used in assembly API getJS getKS

◆ TEST_buildGeometricStiffnessMatrix

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_buildGeometricStiffnessMatrix = 16
staticconstexpr

testing buildGeometricStiffnessMatrix

◆ TEST_GEOMETRIC_STIFFNESS

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_GEOMETRIC_STIFFNESS = TEST_applyDJT | TEST_getK | TEST_buildGeometricStiffnessMatrix
staticconstexpr

testing functions used in assembly API getJS getKS

◆ TEST_getJs

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_getJs = 1
staticconstexpr

testing getJs used in assembly API

◆ TEST_getK

template<class _Mapping >
constexpr unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_getK = 2
staticconstexpr

testing getK used in assembly API

Constructor details

◆ Mapping_test() [1/2]

template<class _Mapping >
sofa::mapping_test::Mapping_test< _Mapping >::Mapping_test ( )
inline

◆ Mapping_test() [2/2]

template<class _Mapping >
sofa::mapping_test::Mapping_test< _Mapping >::Mapping_test ( std::string  fileName)
inline

◆ ~Mapping_test()

template<class _Mapping >
sofa::mapping_test::Mapping_test< _Mapping >::~Mapping_test ( )
inlineoverride

Function details

◆ applyDJT()

template<class _Mapping >
const VecDeriv_t<In>& sofa::mapping_test::Mapping_test< _Mapping >::applyDJT ( core::MechanicalParams  mparams,
bool  updateK 
)
inlineprotected

◆ checkApplyDJT()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::checkApplyDJT ( const VecDeriv_t< In > &  dfp,
const VecDeriv_t< In > &  fp12,
Real_t< In errorThreshold,
bool  updateK 
)
inlineprotected

◆ checkComparisonThreshold()

template<class _Mapping >
void sofa::mapping_test::Mapping_test< _Mapping >::checkComparisonThreshold ( )
inlineprotected

◆ checkJacobianMatrix()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::checkJacobianMatrix ( EigenSparseMatrix jacobianMatrix,
const VecDeriv_t< In > &  velocityIn,
const VecDeriv_t< Out > &  expectedVelocityOut,
Real_t< In errorThreshold 
)
inlineprotected

◆ checkJacobianMatrixTranspose()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::checkJacobianMatrixTranspose ( EigenSparseMatrix jacobianMatrix,
const VecDeriv_t< Out > &  forceOut,
const VecDeriv_t< In > &  expectedForceIn,
Real_t< In errorThreshold 
)
inlineprotected

◆ computeForceChange()

template<class _Mapping >
VecDeriv_t<In> sofa::mapping_test::Mapping_test< _Mapping >::computeForceChange ( core::MechanicalParams  mparams,
const std::size_t  sizeIn,
VecDeriv_t< Out forceOut,
VecDeriv_t< In forceIn 
)
inlineprotected

◆ computeForceInFromForceOut()

template<class _Mapping >
void sofa::mapping_test::Mapping_test< _Mapping >::computeForceInFromForceOut ( core::MechanicalParams  mparams,
VecDeriv_t< In > &  forceIn,
const VecDeriv_t< Out > &  forceOut 
)
inlineprotected

◆ computePerturbedPositions()

template<class _Mapping >
VecCoord_t<In> sofa::mapping_test::Mapping_test< _Mapping >::computePerturbedPositions ( const std::size_t  sizeIn,
const VecDeriv_t< In velocityIn 
)
inlineprotected

◆ computeVelocityOutFromVelocityIn()

template<class _Mapping >
void sofa::mapping_test::Mapping_test< _Mapping >::computeVelocityOutFromVelocityIn ( core::MechanicalParams  mparams,
VecDeriv_t< Out > &  velocityOut,
const VecDeriv_t< In > &  velocityIn 
)
inlineprotected

◆ difference() [1/2]

template<class _Mapping >
virtual Deriv_t<Out> sofa::mapping_test::Mapping_test< _Mapping >::difference ( const Coord_t< Out > &  a,
const Coord_t< Out > &  b 
)
inlineprotectedvirtual

Returns OutCoord substraction a-b

◆ difference() [2/2]

template<class _Mapping >
virtual VecDeriv_t<Out> sofa::mapping_test::Mapping_test< _Mapping >::difference ( const VecDeriv_t< Out > &  a,
const VecDeriv_t< Out > &  b 
)
inlineprotectedvirtual

◆ generateRandomVecDeriv()

template<class _Mapping >
template<class DataTypes >
VecDeriv_t<DataTypes> sofa::mapping_test::Mapping_test< _Mapping >::generateRandomVecDeriv ( const std::size_t  size,
const Real_t< DataTypes minMagnitude,
const Real_t< DataTypes maxMagnitude 
)
inlineprotected

◆ getMatrix()

template<class _Mapping >
template<class EigenSparseMatrixType >
static EigenSparseMatrixType* sofa::mapping_test::Mapping_test< _Mapping >::getMatrix ( const type::vector< sofa::linearalgebra::BaseMatrix * > *  matrices)
inlinestaticprotected

Get one EigenSparseMatrix out of a list. Error if not one single matrix in the list.

◆ isTestExecuted()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::isTestExecuted ( const unsigned char  testFlag) const
inline

Returns true if the test of the method corresponding to the flag parameter must be executed, false otherwise.

◆ preTreatment()

template<class _Mapping >
virtual VecDeriv_t<Out> sofa::mapping_test::Mapping_test< _Mapping >::preTreatment ( const VecDeriv_t< Out > &  f)
inlineprotectedvirtual

Possible child force pre-treatment, does nothing by default

◆ runTest() [1/2]

template<class _Mapping >
virtual bool sofa::mapping_test::Mapping_test< _Mapping >::runTest ( const VecCoord_t< In > &  parent,
const VecCoord_t< Out expectedChild 
)
inlinevirtual

Test the mapping using the given values and small changes. Return true in case of success, if all errors are below maxError*epsilon. The mapping is initialized using the first parameter,

Warning
this version supposes the mapping initialization does not depend on child positions otherwise, use the runTest functions with 4 parameters the child position is computed from parent position and compared with the expected one. Additionally, the Jacobian-related methods are tested using finite differences.
Parameters
parentparent position
expectedChildexpected position of the child corresponding to the parent position

◆ runTest() [2/2]

template<class _Mapping >
virtual bool sofa::mapping_test::Mapping_test< _Mapping >::runTest ( const VecCoord_t< In > &  parentInit,
const VecCoord_t< Out > &  childInit,
const VecCoord_t< In > &  parentNew,
const VecCoord_t< Out > &  expectedChildNew 
)
inlinevirtual

Test the mapping using the given values and small changes. Return true in case of success, if all errors are below maxError*epsilon. The mapping is initialized using the two first parameters, then a new parent position is applied, and the new child position is compared with the expected one. Additionally, the Jacobian-related methods are tested using finite differences.

The initialization values can used when the mapping is an embedding, e.g. to attach a mesh to a rigid object we compute the local coordinates of the vertices based on their world coordinates and the frame coordinates. In other cases, such as mapping from pairs of points to distances, no initialization values are necessary, an one can use the same values as for testing, i.e. runTest( xp, expected_xc, xp, expected_xc).

Parameters
parentInitinitial parent position
childInitinitial child position
parentNewnew parent position
expectedChildNewexpected position of the child corresponding to the new parent position

◆ setTestExecution()

template<class _Mapping >
void sofa::mapping_test::Mapping_test< _Mapping >::setTestExecution ( const unsigned char  testFlag,
const bool  doTheTest 
)
inline

Defines if a test of the method corresponding to the flag parameter must be executed or not.

◆ testApplyJonPosition()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::testApplyJonPosition ( core::MechanicalParams  mparams,
const VecCoord_t< Out > &  positionOut,
const VecDeriv_t< Out > &  expectedVelocityOut,
Real_t< In errorThreshold 
)
inlineprotected

◆ testBuildGeometricStiffnessMatrix()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::testBuildGeometricStiffnessMatrix ( std::size_t  sizeIn,
const VecDeriv_t< In > &  velocityIn,
const VecDeriv_t< In > &  forceChange,
Real_t< In errorThreshold 
)
inlineprotected

◆ testGetK()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::testGetK ( const std::size_t &  sizeIn,
const VecDeriv_t< In > &  velocityIn,
const VecDeriv_t< In > &  forceChange,
Real_t< In errorThreshold 
)
inlineprotected

◆ testMappingPositionVelocity()

template<class _Mapping >
bool sofa::mapping_test::Mapping_test< _Mapping >::testMappingPositionVelocity ( const VecCoord_t< In > &  parentInit,
const VecCoord_t< Out > &  childInit,
const VecCoord_t< In > &  parentNew,
const VecCoord_t< Out > &  expectedChildNew,
const Real_t< In errorThreshold,
core::MechanicalParams  mparams 
)
inlineprotected

◆ warnMissingTests()

template<class _Mapping >
void sofa::mapping_test::Mapping_test< _Mapping >::warnMissingTests ( ) const
inlineprotected