SOFA API  1a4bb3e7
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 InVecCoord& parentInit, const OutVecCoord& childInit, const InVecCoord parentNew, const OutVecCoord 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...
 
simulation::Simulationsimulation
 created by the constructor an re-used in the tests More...
 
std::pair< Real, RealdeltaRange
 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 errorMax
 The test is successfull if the (infinite norm of the) difference is less than errorMax * numeric_limits<Real>::epsilon. More...
 
Real errorFactorDJ
 The test for geometric stiffness is successfull 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 const unsigned char TEST_getJs = 1
 testing getJs used in assembly API More...
 
static const unsigned char TEST_getK = 2
 testing getK used in assembly API More...
 
static const unsigned char TEST_applyJT_matrix = 4
 testing applyJT on matrices More...
 
static const unsigned char TEST_applyDJT = 8
 testing applyDJT More...
 
static const unsigned char TEST_ASSEMBLY_API = TEST_getJs | TEST_getK
 testing functions used in assembly API getJS getKS More...
 
static const unsigned char TEST_GEOMETRIC_STIFFNESS = TEST_applyDJT | TEST_getK
 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

 Mapping_test ()
 
 Mapping_test (std::string fileName)
 
virtual OutDeriv difference (const OutCoord &a, const OutCoord &b)
 
virtual OutVecDeriv difference (const OutVecDeriv &a, const OutVecDeriv &b)
 
virtual OutVecDeriv preTreatment (const OutVecDeriv &f)
 
virtual bool runTest (const InVecCoord &parentInit, const OutVecCoord &childInit, const InVecCoord &parentNew, const OutVecCoord &expectedChildNew)
 
virtual bool runTest (const InVecCoord &parent, const OutVecCoord 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 onSetUp ()
 
virtual void onTearDown ()
 
- 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...
 

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,Real> 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 sofa::mapping_test::Mapping_test< _Mapping >::errorFactorDJ

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

◆ errorMax

template<class _Mapping >
Real sofa::mapping_test::Mapping_test< _Mapping >::errorMax

The test is successfull 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.

◆ simulation

template<class _Mapping >
simulation::Simulation* sofa::mapping_test::Mapping_test< _Mapping >::simulation

created by the constructor an re-used in the tests

◆ TEST_applyDJT

template<class _Mapping >
const unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_applyDJT = 8
static

testing applyDJT

◆ TEST_applyJT_matrix

template<class _Mapping >
const unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_applyJT_matrix = 4
static

testing applyJT on matrices

◆ TEST_ASSEMBLY_API

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

testing functions used in assembly API getJS getKS

◆ TEST_GEOMETRIC_STIFFNESS

template<class _Mapping >
const unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_GEOMETRIC_STIFFNESS = TEST_applyDJT | TEST_getK
static

testing functions used in assembly API getJS getKS

◆ TEST_getJs

template<class _Mapping >
const unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_getJs = 1
static

testing getJs used in assembly API

◆ TEST_getK

template<class _Mapping >
const unsigned char sofa::mapping_test::Mapping_test< _Mapping >::TEST_getK = 2
static

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

◆ difference() [1/2]

template<class _Mapping >
virtual OutDeriv sofa::mapping_test::Mapping_test< _Mapping >::difference ( const OutCoord a,
const OutCoord b 
)
inlinevirtual

Returns OutCoord substraction a-b

◆ difference() [2/2]

template<class _Mapping >
virtual OutVecDeriv sofa::mapping_test::Mapping_test< _Mapping >::difference ( const OutVecDeriv a,
const OutVecDeriv b 
)
inlinevirtual

◆ 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.

◆ preTreatment()

template<class _Mapping >
virtual OutVecDeriv sofa::mapping_test::Mapping_test< _Mapping >::preTreatment ( const OutVecDeriv f)
inlinevirtual

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 InVecCoord parent,
const OutVecCoord  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 depends 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 InVecCoord parentInit,
const OutVecCoord childInit,
const InVecCoord parentNew,
const OutVecCoord 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