From: vbd Date: Tue, 12 Feb 2008 13:05:52 +0000 (+0000) Subject: modifying test toolkit so that it checks for 2D meshes X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=508363c279b5e59e32c3ea26faacb6c21e00d74e;p=tools%2Fmedcoupling.git modifying test toolkit so that it checks for 2D meshes adding 2D tests (unit and validation) to the test base --- diff --git a/src/INTERP_KERNEL/Test/HexaTests.hxx b/src/INTERP_KERNEL/Test/HexaTests.hxx index 19ff13edc..faf6431f8 100644 --- a/src/INTERP_KERNEL/Test/HexaTests.hxx +++ b/src/INTERP_KERNEL/Test/HexaTests.hxx @@ -1,7 +1,7 @@ #ifndef __HEXA_TESTS_HXX_ #define __HEXA_TESTS_HXX_ -#include "Interpolation3DTestSuite.hxx" +#include "InterpolationTestSuite.hxx" namespace INTERP_TEST { @@ -9,7 +9,7 @@ namespace INTERP_TEST * \brief Class performing intersection tests on meshes with hexahedral elements. * */ - class HexaTests : public Interpolation3DTestSuite + class HexaTests : public InterpolationTestSuite<3,3> { CPPUNIT_TEST_SUITE( HexaTests ); diff --git a/src/INTERP_KERNEL/Test/Interpolation3DTestSuite.hxx b/src/INTERP_KERNEL/Test/Interpolation3DTestSuite.hxx deleted file mode 100644 index f790eba85..000000000 --- a/src/INTERP_KERNEL/Test/Interpolation3DTestSuite.hxx +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __TU_INTERPOLATION_3D_TEST_SUITE_HXX__ -#define __TU_INTERPOLATION_3D_TEST_SUITE_HXX__ - -#include "MeshTestToolkit.hxx" - -#include - -namespace INTERP_TEST -{ - - /** - * \brief Base class for mesh intersection test suites. - * - */ - class Interpolation3DTestSuite : public CppUnit::TestFixture - { - - public: - /** - * Sets up the test suite. - * Creates the MeshTestToolkit object used by the tests. - * - */ - void setUp() - { - _testTools = new MeshTestToolkit(); - } - - /** - * Cleans up after the test suite. - * Liberates the MeshTestToolkit object used by the tests. - */ - void tearDown() - { - delete _testTools; - } - - - - protected: - /// MeshTestToolkit object to which the tests are delegated - MeshTestToolkit* _testTools; - - }; -} -#endif diff --git a/src/INTERP_KERNEL/Test/InterpolationPlanarTestSuite.hxx b/src/INTERP_KERNEL/Test/InterpolationPlanarTestSuite.hxx new file mode 100755 index 000000000..a937390d3 --- /dev/null +++ b/src/INTERP_KERNEL/Test/InterpolationPlanarTestSuite.hxx @@ -0,0 +1,109 @@ +#ifndef __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ + +#include +#include +#include + +using namespace std; + +namespace INTERP_TEST +{ + + /** + * \brief Base class for planar mesh intersection test suites. + * + */ + class InterpolationPlanarTestSuite : public CppUnit::TestFixture + { + + public: + double _Epsilon; + double _Precision; + + /** + * Sets up the test suite. + * + */ + void setUp() + { + _Epsilon = 1.e-6; + _Precision = 1.e-6; + } + void tearDown() {} + +// bool checkDequesEqual(std::deque< double > deque1, std::deque< double > deque2, double epsilon); +// bool checkVectorsEqual(std::vector< double > Vect1, std::vector< double > Vect2, double epsilon); +// void dequePrintOut(std::deque< double > deque1); +// void vectPrintOut(std::vector< double > vect); +// void tabPrintOut( const double * tab, int size); + + bool checkDequesEqual(std::deque< double > deque1, + std::deque< double > deque2, double epsilon) + { + int size1 = deque1.size(); + int size2 = deque2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(deque1[i] - deque2[i]) < epsilon; + + return are_equal; + } + bool checkVectorsEqual(std::vector< double > vect1, + std::vector< double > vect2, double epsilon) + { + int size1 = vect1.size(); + int size2 = vect2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(vect1[i] - vect2[i]) < epsilon; + + return are_equal; + } + void dequePrintOut(std::deque< double > deque1) + { + for(int i = 0; i< (int)deque1.size(); i++) + { + cerr << deque1[i] << " "; + } + cerr<< endl; + } + void vectPrintOut(std::vector< double > vect) + { + for(int i = 0; i< (int)vect.size(); i++) + { + cerr << vect[i] << " "; + } + cerr<< endl; + } + void tabPrintOut( const double * tab,int size) + { + for(int i = 0; i< size; i++) + { + cerr << tab[i] << " "; + } + cerr<< endl; + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ +// void tearDown() +// { +// delete _testTools; +// } + + + +// protected: +// /// MeshTestToolkit object to which the tests are delegated +// MeshTestToolkit* _testTools; + + }; +} +#endif diff --git a/src/INTERP_KERNEL/Test/InterpolationTestSuite.hxx b/src/INTERP_KERNEL/Test/InterpolationTestSuite.hxx new file mode 100644 index 000000000..ea640c1b0 --- /dev/null +++ b/src/INTERP_KERNEL/Test/InterpolationTestSuite.hxx @@ -0,0 +1,47 @@ +#ifndef __TU_INTERPOLATION_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_TEST_SUITE_HXX__ + +#include "MeshTestToolkit.txx" + +#include + +namespace INTERP_TEST +{ + + /** + * \brief Base class for mesh intersection test suites. + * + */ + template + class InterpolationTestSuite : public CppUnit::TestFixture + { + + public: + /** + * Sets up the test suite. + * Creates the MeshTestToolkit object used by the tests. + * + */ + void setUp() + { + _testTools = new MeshTestToolkit(); + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ + void tearDown() + { + delete _testTools; + } + + + + protected: + /// MeshTestToolkit object to which the tests are delegated + MeshTestToolkit* _testTools; + + }; +} +#endif diff --git a/src/INTERP_KERNEL/Test/Makefile.am b/src/INTERP_KERNEL/Test/Makefile.am index db8732510..7c61f9f12 100644 --- a/src/INTERP_KERNEL/Test/Makefile.am +++ b/src/INTERP_KERNEL/Test/Makefile.am @@ -27,13 +27,15 @@ lib_LTLIBRARIES = libInterpKernelTest.la salomeinclude_HEADERS = CppUnitTest.hxx \ TransformedTriangleTest.hxx \ TransformedTriangleIntersectTest.hxx \ - Interpolation3DTestSuite.hxx \ + InterpolationTestSuite.hxx \ SingleElementTetraTests.hxx \ MultiElementTetraTests.hxx \ HexaTests.hxx \ MeshTestToolkit.hxx \ BBTreeTest.hxx \ - RemapperTest.cxx + RemapperTest.hxx \ + SingleElementPlanarTests.hxx \ + MultiElementPlanarTests.hxx EXTRA_DIST += BasicMainTest.hxx @@ -41,9 +43,9 @@ dist_libInterpKernelTest_la_SOURCES= \ CppUnitTest.cxx \ TransformedTriangleTest.cxx \ TransformedTriangleIntersectTest.cxx \ - MeshTestToolkit.cxx \ BBTreeTest.cxx \ - RemapperTest.cxx + RemapperTest.cxx \ + SingleElementPlanarTests.cxx libInterpKernelTest_la_CPPFLAGS= @CPPUNIT_INCLUDES@ $(MED2_INCLUDES) $(HDF5_INCLUDES) \ -I$(srcdir)/.. -I$(srcdir)/../../MEDWrapper/V2_1/Core -I$(srcdir)/../../MEDMEM -DOPTIMIZE -DLOG_LEVEL=0 diff --git a/src/INTERP_KERNEL/Test/MeshTestToolkit.cxx b/src/INTERP_KERNEL/Test/MeshTestToolkit.cxx deleted file mode 100644 index a67b0811b..000000000 --- a/src/INTERP_KERNEL/Test/MeshTestToolkit.cxx +++ /dev/null @@ -1,444 +0,0 @@ -#include "MEDNormalizedUnstructuredMesh.hxx" -#include "MEDNormalizedUnstructuredMesh.txx" - -#include "MeshTestToolkit.hxx" -#include "MEDMEM_Mesh.hxx" -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" - -#include -#include -#include -#include -#include - -#include "VectorUtils.hxx" - -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Support.hxx" - -// levels : -// 1 - titles and volume results -// 2 - symmetry / diagonal results and intersection matrix output -// 3 - empty -// 4 - empty -// 5 - misc -#include "Log.hxx" - -#include - -//#define VOL_PREC 1.0e-6 - -using namespace MEDMEM; -using namespace std; -using namespace MED_EN; -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - - /** - * Calculates the sum of a row of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the row (1 <= i <= no. rows) - * @return the sum of the values of row i - * - */ - double MeshTestToolkit::sumRow(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - if(iter->count(i) != 0.0) - { - map::const_iterator iter2 = iter->find(i); - vol += iter2->second; - } - } - return vol; - } - - /** - * Calculates the sum of a column of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the column (0 <= i <= no. rows - 1) - * @return the sum of the values of column i - * - */ - double MeshTestToolkit::sumCol(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - const std::map& col = m[i]; - for(map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) - { - vol += std::abs(iter->second); - } - return vol; - } - - /** - * Gets the volumes of the elements in a mesh. - * - * @param mesh the mesh - * @param tab pointer to double[no. elements of mesh] array in which to store the volumes - */ - void MeshTestToolkit::getVolumes(MEDMEM::MESH& mesh, const double*& tab) const - { - SUPPORT *sup=new SUPPORT(&mesh,"dummy",MED_CELL); - FIELD* f=mesh.getVolume(sup); - tab = f->getValue(); - delete sup; - } - - /** - * Sums all the elements (volumes) of an intersection matrix - * - * @param m the intersection matrix - * @return the sum of the elements of m - */ - double MeshTestToolkit::sumVolume(const IntersectionMatrix& m) const - { - - vector volumes; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - volumes.push_back(iter2->second); - } - } - - // sum in ascending order to avoid rounding errors - - sort(volumes.begin(), volumes.end()); - const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); - - return vol; - } - - /** - * Verifies if for a given intersection matrix the sum of each row is equal to the volumes - * of the corresponding source elements and the sum of each column is equal to the volumes - * of the corresponding target elements. This will be true as long as the meshes correspond - * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative - * error is small enough. - * - * @param m the intersection matrix - * @param sMesh the source mesh - * @param tMesh the target mesh - * @return true if the condition is verified, false if not. - */ - bool MeshTestToolkit::testVolumes(const IntersectionMatrix& m, MEDMEM::MESH& sMesh, MEDMEM::MESH& tMesh) const - { - bool ok = true; - - // source elements - const double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; - getVolumes(sMesh, sVol); - - for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) - { - const double sum_row = sumRow(m, i+1); - if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) - { - LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); - ok = false; - } - LOG(1, "diff = " <::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double v1 = iter2->second; - //if(m2[j - 1].count(i+1) > 0) - // { - map theMap = m2.at(j-1); - const double v2 = theMap[i + 1]; - if(v1 != v2) - { - LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); - if(!epsilonEqualRelative(v1, v2, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isSymmetric = false; - } - } - } - ++i; - } - if(!isSymmetric) - { - LOG(1, "*** matrices are not symmetric"); - } - return isSymmetric; - } - - /** - * Tests if an intersection matrix is diagonal. - * - * @param m the intersection matrix - * @return true if m is diagonal; false if not - * - */ - bool MeshTestToolkit::testDiagonal(const IntersectionMatrix& m) const - { - LOG(1, "Checking if matrix is diagonal" ); - int i = 1; - bool isDiagonal = true; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double vol = iter2->second; - if(vol != 0.0 && (i != j)) - { - LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); - if(!epsilonEqual(vol, 0.0, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isDiagonal = false; - } - } - } - ++i; - } - if(!isDiagonal) - { - LOG(1, "*** matrix is not diagonal"); - } - return isDiagonal; - } - - /** - * Outputs the intersection matrix as a list of all its elements to std::cout. - * - * @param m the intersection matrix to output - */ - void MeshTestToolkit::dumpIntersectionMatrix(const IntersectionMatrix& m) const - { - int i = 0; - std::cout << "Intersection matrix is " << endl; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - - std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << endl; - - } - ++i; - } - std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; - } - - /** - * Calculates the intersection matrix for two meshes. - * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh2 the name of the target mesh - * @param m intersection matrix in which to store the result of the intersection - */ - void MeshTestToolkit::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const - { - const string dataBaseDir = getenv("MED_ROOT_DIR"); - const string dataDir = dataBaseDir + string("/share/salome/resources/MedFiles/"); - - LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); - - MEDNormalizedUnstructuredMesh<3,3> sMesh_wrapper(&sMesh); - MEDNormalizedUnstructuredMesh<3,3> tMesh_wrapper(&tMesh); - - _interpolator->interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); - - // if reflexive, check volumes - if(strcmp(mesh1path,mesh2path) == 0) - { - const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); - } - - LOG(1, "Intersection calculation done. " << std::endl ); - - } - - /** - * Tests the intersection algorithm for two meshes. - * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will - * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then - * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be - * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - void MeshTestToolkit::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - LOG(1, std::endl << std::endl << "=============================" ); - - using std::string; - const string path1 = string(mesh1path) + string(mesh1); - const string path2 = string(mesh2path) + string(mesh2); - - const bool isTestReflexive = (path1.compare(path2) == 0); - - IntersectionMatrix matrix1; - calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix1); -#endif - - std::cout.precision(16); - - const double vol1 = sumVolume(matrix1); - - if(!doubleTest) - { - LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); - - if(isTestReflexive) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); - } - } - else - { - - IntersectionMatrix matrix2; - calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix2); -#endif - - const double vol2 = sumVolume(matrix2); - - LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); - } - - } - - /** - * Utility method used to facilitate the call to intersect meshes. - * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and - * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed - * along as they are. - * - * @param mesh1 the name of the source mesh - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - void MeshTestToolkit::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - const string path1 = string(mesh1) + string(".med"); - std::cout << "here :" << path1 << std::endl; - const string path2 = string(mesh2) + string(".med"); - - intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); - } - - -} diff --git a/src/INTERP_KERNEL/Test/MeshTestToolkit.hxx b/src/INTERP_KERNEL/Test/MeshTestToolkit.hxx index 40c68fb31..9ac73cb72 100644 --- a/src/INTERP_KERNEL/Test/MeshTestToolkit.hxx +++ b/src/INTERP_KERNEL/Test/MeshTestToolkit.hxx @@ -27,14 +27,15 @@ namespace INTERP_TEST * \brief Class providing services for mesh intersection tests. * */ + template class MeshTestToolkit { public: - MeshTestToolkit() : _interpolator(new INTERP_KERNEL::Interpolation3D()) {} + MeshTestToolkit() {} - ~MeshTestToolkit() { delete _interpolator; } + ~MeshTestToolkit() {} void intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; @@ -61,11 +62,6 @@ namespace INTERP_TEST void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const; - protected: - - /// Interpolation3D object used for interpolation - INTERP_KERNEL::Interpolation3D* _interpolator; - }; } #endif diff --git a/src/INTERP_KERNEL/Test/MeshTestToolkit.txx b/src/INTERP_KERNEL/Test/MeshTestToolkit.txx new file mode 100644 index 000000000..b54e4ee4e --- /dev/null +++ b/src/INTERP_KERNEL/Test/MeshTestToolkit.txx @@ -0,0 +1,485 @@ +#include "MEDNormalizedUnstructuredMesh.hxx" +#include "MEDNormalizedUnstructuredMesh.txx" + +#include "MeshTestToolkit.hxx" +#include "MEDMEM_Mesh.hxx" + +#include "Interpolation3DSurf.txx" +#include "Interpolation2D.txx" +#include "Interpolation3D.txx" + +#include +#include +#include +#include +#include + +#include "VectorUtils.hxx" + +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Support.hxx" + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + +#include + +//#define VOL_PREC 1.0e-6 + +using namespace MEDMEM; +using namespace std; +using namespace MED_EN; +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + /** + * Calculates the sum of a row of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the row (1 <= i <= no. rows) + * @return the sum of the values of row i + * + */ + template + double MeshTestToolkit::sumRow(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + if(iter->count(i) != 0.0) + { + map::const_iterator iter2 = iter->find(i); + vol += iter2->second; + } + } + return vol; + } + + /** + * Calculates the sum of a column of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the column (0 <= i <= no. rows - 1) + * @return the sum of the values of column i + * + */ + template + double MeshTestToolkit::sumCol(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + const std::map& col = m[i]; + for(map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) + { + vol += std::abs(iter->second); + } + return vol; + } + + /** + * Gets the volumes of the elements in a mesh. + * + * @param mesh the mesh + * @param tab pointer to double[no. elements of mesh] array in which to store the volumes + */ + template + void MeshTestToolkit::getVolumes(MEDMEM::MESH& mesh, const double*& tab) const + { + SUPPORT *sup=new SUPPORT(&mesh,"dummy",MED_CELL); + FIELD* f; + switch (MESHDIM) + { + case 2: + f=mesh.getArea(sup); + break; + case 3: + f=mesh.getVolume(sup); + break; + } + tab = f->getValue(); + delete sup; + } + + /** + * Sums all the elements (volumes) of an intersection matrix + * + * @param m the intersection matrix + * @return the sum of the elements of m + */ + + template + double MeshTestToolkit::sumVolume(const IntersectionMatrix& m) const + { + + vector volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(iter2->second); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; + } + + /** + * Verifies if for a given intersection matrix the sum of each row is equal to the volumes + * of the corresponding source elements and the sum of each column is equal to the volumes + * of the corresponding target elements. This will be true as long as the meshes correspond + * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative + * error is small enough. + * + * @param m the intersection matrix + * @param sMesh the source mesh + * @param tMesh the target mesh + * @return true if the condition is verified, false if not. + */ + template + bool MeshTestToolkit::testVolumes(const IntersectionMatrix& m, MEDMEM::MESH& sMesh, MEDMEM::MESH& tMesh) const + { + bool ok = true; + + // source elements + const double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; + getVolumes(sMesh, sVol); + + for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) + { + const double sum_row = sumRow(m, i+1); + if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) + { + LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); + ok = false; + } + LOG(1, "diff = " < + bool MeshTestToolkit::testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const + { + + int i = 0; + bool isSymmetric = true; + + LOG(1, "Checking symmetry src - target" ); + isSymmetric = isSymmetric & areCompatitable(m1, m2) ; + LOG(1, "Checking symmetry target - src" ); + isSymmetric = isSymmetric & areCompatitable(m2, m1); + + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = iter2->second; + //if(m2[j - 1].count(i+1) > 0) + // { + map theMap = m2.at(j-1); + const double v2 = theMap[i + 1]; + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; + } + + /** + * Tests if an intersection matrix is diagonal. + * + * @param m the intersection matrix + * @return true if m is diagonal; false if not + * + */ + template + bool MeshTestToolkit::testDiagonal(const IntersectionMatrix& m) const + { + LOG(1, "Checking if matrix is diagonal" ); + int i = 1; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; + } + + /** + * Outputs the intersection matrix as a list of all its elements to std::cout. + * + * @param m the intersection matrix to output + */ + template + void MeshTestToolkit::dumpIntersectionMatrix(const IntersectionMatrix& m) const + { + int i = 0; + std::cout << "Intersection matrix is " << endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << endl; + + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; + } + + /** + * Calculates the intersection matrix for two meshes. + * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param m intersection matrix in which to store the result of the intersection + */ + template + void MeshTestToolkit::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const + { + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + string("/share/salome/resources/MedFiles/"); + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + + MEDNormalizedUnstructuredMesh sMesh_wrapper(&sMesh); + MEDNormalizedUnstructuredMesh tMesh_wrapper(&tMesh); + + if (SPACEDIM==2 && MESHDIM==2) + { + Interpolation2D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); + } + else if (SPACEDIM==3 && MESHDIM==2) + { + Interpolation3DSurf interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); + } + else if (SPACEDIM==3 && MESHDIM==3) + { + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); + } + else + { + throw MEDEXCEPTION("Wrong dimensions"); + } + // if reflexive, check volumes + if(strcmp(mesh1path,mesh2path) == 0) + { + const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); + } + + LOG(1, "Intersection calculation done. " << std::endl ); + + } + + /** + * Tests the intersection algorithm for two meshes. + * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will + * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then + * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be + * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template + void MeshTestToolkit::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); + } + + } + + /** + * Utility method used to facilitate the call to intersect meshes. + * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and + * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed + * along as they are. + * + * @param mesh1 the name of the source mesh + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template + void MeshTestToolkit::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + const string path1 = string(mesh1) + string(".med"); + std::cout << "here :" << path1 << std::endl; + const string path2 = string(mesh2) + string(".med"); + + intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); + } + + +} diff --git a/src/INTERP_KERNEL/Test/MultiElement2DTests.hxx b/src/INTERP_KERNEL/Test/MultiElement2DTests.hxx new file mode 100644 index 000000000..7aa8e69c7 --- /dev/null +++ b/src/INTERP_KERNEL/Test/MultiElement2DTests.hxx @@ -0,0 +1,34 @@ +#ifndef __MULTI_ELEMENT_PLANAR_TESTS_HXX_ +#define __MULTI_ELEMENT_PLANAR_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" +#include "Interpolation2D.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * polygonal elements - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : triangle, quadrilateral. + * + */ + class MultiElement2DTests : public InterpolationTestSuite<2,2> + { + CPPUNIT_TEST_SUITE( MultiElement2DTests ); + + CPPUNIT_TEST(Volume2DTriangulationTest); + + CPPUNIT_TEST_SUITE_END(); + + public: + void Volume2DTriangulationTest() + { + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + } + + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Test/MultiElementTetraTests.hxx b/src/INTERP_KERNEL/Test/MultiElementTetraTests.hxx index 4da06f233..9390b9f61 100644 --- a/src/INTERP_KERNEL/Test/MultiElementTetraTests.hxx +++ b/src/INTERP_KERNEL/Test/MultiElementTetraTests.hxx @@ -1,7 +1,7 @@ #ifndef __MULTI_ELEMENT_TETRA_TESTS_HXX_ #define __MULTI_ELEMENT_TETRA_TESTS_HXX_ -#include "Interpolation3DTestSuite.hxx" +#include "InterpolationTestSuite.hxx" namespace INTERP_TEST { @@ -13,7 +13,7 @@ namespace INTERP_TEST * different geometries : tetrahedra, boxes and cylinders. * */ - class MultiElementTetraTests : public Interpolation3DTestSuite + class MultiElementTetraTests : public InterpolationTestSuite<3,3> { CPPUNIT_TEST_SUITE( MultiElementTetraTests ); diff --git a/src/INTERP_KERNEL/Test/PerfTest.cxx b/src/INTERP_KERNEL/Test/PerfTest.cxx index 2b20d70ab..6d141be08 100644 --- a/src/INTERP_KERNEL/Test/PerfTest.cxx +++ b/src/INTERP_KERNEL/Test/PerfTest.cxx @@ -1,6 +1,6 @@ #include "Interpolation3D.hxx" #include "Interpolation3D.txx" -#include "MeshTestToolkit.hxx" +#include "MeshTestToolkit.txx" #include "Log.hxx" #include "VectorUtils.hxx" @@ -29,7 +29,7 @@ namespace INTERP_TEST * \brief Specialization of MeshTestToolkit for the purposes of performance testing. * */ - class PerfTestToolkit : public MeshTestToolkit + class PerfTestToolkit : public MeshTestToolkit<3,3> { public: @@ -67,7 +67,9 @@ namespace INTERP_TEST MEDNormalizedUnstructuredMesh<3,3> sMesh_wrapper(&sMesh); MEDNormalizedUnstructuredMesh<3,3> tMesh_wrapper(&tMesh); - _interpolator->interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); + + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m); std::pair eff = countNumberOfMatrixEntries(m); LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " diff --git a/src/INTERP_KERNEL/Test/SingleElementPlanarTests.cxx b/src/INTERP_KERNEL/Test/SingleElementPlanarTests.cxx new file mode 100755 index 000000000..15a06597a --- /dev/null +++ b/src/INTERP_KERNEL/Test/SingleElementPlanarTests.cxx @@ -0,0 +1,901 @@ +#ifndef __SINGLE_ELEMENT_PLANAR_TESTS_CXX_ +#define __SINGLE_ELEMENT_PLANAR_TESTS_CXX_ + +#include "SingleElementPlanarTests.hxx" +#include "InterpolationUtils.hxx" +#include + +namespace INTERP_TEST +{ + const double _losange1[8] = { 1,0, 0,1, -1,0, 0,-1 }; + const double _losange2[8] = { 2,0, 1,1, 0,0, 1,-1 }; + const double _losange3[8] = {2.5,0.5,1.5,1.5,0.5,0.5,1.5,-0.5 }; + const double _square1[8] = { -1,-1, -1,1, 1,1, 1,-1}; + const double _square2[8] = {1,-0.25,0,-0.25,0,0.25,1,0.25 }; + const double _losange4[8] = { 3,0, 2,1, 1,0, 2,-1 }; + const double _losange5[8] = { 1.5,0, 0,1.5,-1.5,0, 0,-1.5 }; + const double _losange6[12]= { 2,0, 1,1, 0.5,0.5,0,0, 0.5,-0.5, 1,-1 }; + const double _losange7[10]= { 1,0, 0,1, -1,0, 0,-1, 0.5,-0.5 }; + const double _square3[10] = { -1,-1, -1,1, 0.5,1, 1,1, 1,-1, }; + const double _square4[8] = {-0.5,-1,-0.5,1,1.5,1,1.5,-1 }; + const double _square5[10] = { -1,-1, -1,1, 0,1, 1,1, 1,-1 }; + const double _losange8[8] = { 0,1, 1,-1, 0,-1.5,-0.5,-1 }; + const double _losange9[8] = {0.5,0, 0,1, -1.5,0, 0,-1 }; + const double _hexagon1[12]= { -2,0, -1,-1, 1,-1, 2,0, 1,1, -1,1 }; + const double _hexagon2[12]= {-1.5,0.5,-1,-1, 1,-1, 2,1, 1,1, -1,1 }; + const double _hexagon3[12]= { -2,2, -1,1, 1,1, 2,2, 1,3, -1,3 }; + const double _square6[8] = { -1,1, -1,3, 0.5,3,0.5,1 }; + const double _losange10[8]= { 0,-1, 1,-2, 0,-3, -1,-2 }; + const double _triangle1[6]= {0.5,0, 1,1, 0,1 }; + const double _triangle2[6]= { 0,0.5, 0,-0.5,1.5,0 }; + const double _triangle3[9]= {-1,2,0, 1,2,0, 0,2,1 }; + const double _triangle4[9]= {1./2,2,0, 1, 2, 1, 1, 2, 0.5 }; + const double _parallel1[8] = {-1,0, -0.5,1, 0.5,1, 0,0}; + const double _parallel2[8]= {-0.5,1, 0,0, 1.,0, 0.5,1 }; + const double _parallel3[8]= {-0.5,-1, 0,0, 1,0, 0.5,-1}; + const double _triangle5[6]= { 0,0, 0,0.5, 0.5,0.5 }; + const double _triangle6[6]= { 0.333333,0.333333, 0.333333,0.666667, 0.666667,0.666667 }; + + + // Two diamonds intersecting without degeneracy (two distinct crossing points) +// /\ /\ +// / \/ \ +// / /\ \ +// / / \ \ +// \ \ / / +// \ \/ / +// \ /\ / +// \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_losange2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", + checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + + void SingleElementPlanarTests::diamondsBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", + checkVectorsEqual(actual_result, expected_result, _Epsilon)); + } + + +// Two diamonds with overlapping edges in an exclusion configuration +// /\ +// / \ +// /\ / \ +// / \/ \ +// / \ / +// / \ / +// \ /\ / +// \ / \/ +// \ / +// \/ + // \brief Status : pass + void SingleElementPlanarTests::tangentDiamonds() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_losange3,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (CONVEX)", + checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::tangentDiamonds_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (TRIANGULATION)", + checkVectorsEqual(actual_result, expected_result, _Epsilon)); + } + +// Two tangent squares with overlapping edges, in an inclusion configuration +// _____________ +// | | +// | _______| +// | | | +// | |_______| +// | | +// |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::tangentSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_square2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::tangentSquares_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.25); + expected_result.push_back(0.25);expected_result.push_back(0.25); + expected_result.push_back(1./6);expected_result.push_back(1./6); + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two diamonds sharing a vertex in an exclusion configuration +// /\ /\ +// / \ / \ +// / \ / \ +// / \/ \ +// \ /\ / +// \ / \ / +// \ / \ / +// \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsSharingVertex1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_losange4,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::diamondsSharingVertex1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange4,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two identical squares +// _____________ +// | | +// | | +// | | +// | | +// | | +// |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::identicalSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_square1,4,4); + deque< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::identicalSquares_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } +// Square and diamond intersecting with no degeneracy +// /\ +// / \ +// / \ +// __/______\__ +// | / \ | +// |/ \| +// / \ +// /| |\ +// \| |/ +// \ / +// |\ /| +// |_\________/_| +// \ / +// \ / +// \ / +// \/ + // \brief Status : pass + void SingleElementPlanarTests::squareAndDiamondBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_losange5,4,4); + deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::squareAndDiamondBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange5,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.75);expected_result.push_back(0.75); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.75);expected_result.push_back(-0.75); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + // square and diamond intersecting at four degenerated pointss +// ______ +// | /\ | +// | / \ | +// |/ \| +// |\ /| +// | \ / | +// |__\/__| + // \brief Status : pass + + void SingleElementPlanarTests::squareAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_losange1,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::squareAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } +// Two diamonds intersecting at one vertex on edge and one double vertex +// /\ /\ +// / \ / \ +// / ¤ \ +// / / \ \ +// \ \ / / +// \ * / +// \ / \ / +// \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsCritical() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange6,_losange7,6,5); + deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::diamondsCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange6,_losange7,6,5,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two tangent squares with starting and ending vertices on edges +// _____ ___.___ ______ +// | | | | +// | | | | +// | | | | +// | | | | +// | | | | +// |_____|_______|______| + + // \brief Status : pass + void SingleElementPlanarTests::quadranglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square4,_square3,4,5); + deque< double > expected_result; + + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::quadranglesCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square4,_square3,4,5,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + + + // square and diamond crossing and tangency at double vertices, starting vertex on edge +// _____.____ +// | / \ | +// | / \ | +// | / \ | +// |_/_______\| +// \ / +// \ / +// \ / +// \ / + // \brief Status : pass + void SingleElementPlanarTests::quadrangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square5,_losange8,5,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::quadrangleAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square5,_losange8,5,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-1./3);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } // square and diamond intersecting at four degenerated pointss +// +// ²/²\ +// ² / ² \ +// ² / ² \ +// ² \ ² / +// ² \ ² / +// ²\²/ + // \brief Status : pass + + void SingleElementPlanarTests::diamondsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_losange9,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::diamondsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange9,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two tangent hexagons with double vertices and a critical starting vertex on edge + // _________ +// / \²²² +// ² \² +// / \ +// / ² ² \ +// \ / +// \ ² ² / +// \ / +// \²_______²/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical1() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_hexagon1,_hexagon2,6,6); + deque< double > expected_result; + + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::hexagonsCritical1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon2,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-8./7);expected_result.push_back(2./7); + expected_result.push_back(-1.4);expected_result.push_back(0.2); + expected_result.push_back(-4./3);expected_result.push_back(0.); + expected_result.push_back(-2./3);expected_result.push_back(0.); + expected_result.push_back(-1.25);expected_result.push_back(-0.25); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.5);expected_result.push_back(0.); + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.125);expected_result.push_back(0.875); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.25);expected_result.push_back(0.75); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two tangent hexagons with double vertices and a critical starting vertex on edge + // _______ +// / \ +// / \ +// \ / +// \_______/ +// / \ +// / \ +// \ / +// \_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_hexagon1,_hexagon3,6,6); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::hexagonsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon3,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Square and quadrilateron with outer tangency +// ________ +// | | +// | | +// | | +// |________|___ +// | | +// | | +// | | +// | | +// | | +// |____________| + + // \brief Status : pass + void SingleElementPlanarTests::squareAndQuadrangleCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_square6,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::squareAndQuadrangleCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square6,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } +// Two diamonds sharing a vertex in an exclusion configuration +// /\ +// / \ +// / \ +// / \ +// \ / +// \ / +// \ / +// \/ +// /\ +// / \ +// / \ +// / \ +// \ / +// \ / +// \ / +// \/ + + + // \brief Status : pass + void SingleElementPlanarTests:: diamondsSharingVertex2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_losange10,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests:: diamondsSharingVertex2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange10,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Triangle and diamond with a critical crossing at double starting vertex +// ____ +// /|\ / +// / | \/ +// / | /\ +// / |/ \ +// \ / +// \ / +// \ / +// \ / + + // \brief Status : pass + void SingleElementPlanarTests:: triangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_losange1,_triangle1,4,3); + deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests:: triangleAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_triangle1,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Basic triangle and square intersection (two distinct points) +// __________ +// | | +// | |\ | +// | | \| +// | | \ +// | | |\ +// | | |/ +// | | / +// | | /| +// | |/ | +// |__________| + + // \brief Status : pass + void SingleElementPlanarTests::triangleAndSquareBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_square1,_triangle2,4,3); + deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(1.);expected_result.push_back(-1./6); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(0.5); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + + void SingleElementPlanarTests::triangleAndSquareBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_triangle2,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(0.375);expected_result.push_back(0.375); + expected_result.push_back(0.);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(1.);expected_result.push_back(-1./6); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } +// Two triangles with a starting vertex on edge + +// /\ ²²²² +// / ² ² +// / ² ² +// /__²___\ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<3> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_triangle3,_triangle4,3,3); + deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(2.);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(2.);expected_result.push_back(0.); + expected_result.push_back(0.75);expected_result.push_back(2.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::trianglesCritical_Triangulation() + { + vector< double > actual_result; + double _triangle3rotated[6],_triangle4rotated[6]; + for (int i=0; i<3; i++)_triangle3rotated[2*i] = _triangle3[3*i]; + for (int i=0; i<3; i++)_triangle3rotated[2*i+1] = _triangle3[3*i+2]; + for (int i=0; i<3; i++)_triangle4rotated[2*i] = _triangle4[3*i]; + for (int i=0; i<3; i++)_triangle4rotated[2*i+1] = _triangle4[3*i+2]; + + INTERP_KERNEL::intersec_de_polygone<2>(_triangle3rotated,_triangle4rotated,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.75);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two tangent paralellograms intersecting at 3 double vertices (one being a starting vertex) +// _______ +// /\ /\ +// / \ / \ +// / \ / \ +// /______\/______\ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_parallel1,_parallel2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::paralellogramsCritical1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.25);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(2./3); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.25);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two paralellograms sharing a vertex in an exclusion configuration +// ________ +// / / +// / / +// / / +// /_______/_______ +// / / +// / / +// / / +// /_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_parallel1,_parallel3,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (2) failed(CONVEX)", + checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::paralellogramsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (2) failed(TRIANGULATION)", + checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +// Two triangles in a tangency configuration with a starting vertex on edge + + // _____ + // | / +// __|___/ +// | | / +// | | / +// | |/ + // | / + // | / + // |/ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersect_convex_polygons(_triangle5,_triangle6,3,3); + deque< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(1./2);expected_result.push_back(1./2); + + if(!checkDequesEqual(actual_result,expected_result, _Epsilon)) + { + cerr<< "CPP_UNIT expected result= " << endl; + dequePrintOut(expected_result); + cerr<< "CPP_UNIT actual result= " << endl; + dequePrintOut(actual_result); + } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed(CONVEX)", checkDequesEqual(actual_result,expected_result, _Epsilon)); + } + void SingleElementPlanarTests::trianglesTangencyCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle5,_triangle6,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./2);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + + if(!checkVectorsEqual(actual_result,expected_result, _Epsilon)) + { + cerr<< "CPP_UNIT expected result= " << endl; + vectPrintOut(expected_result); + cerr<< "CPP_UNIT actual result= " << endl; + vectPrintOut(actual_result); + } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed(TRIANGULATION)", checkVectorsEqual(actual_result,expected_result, _Epsilon)); + } + +} +#endif diff --git a/src/INTERP_KERNEL/Test/SingleElementPlanarTests.hxx b/src/INTERP_KERNEL/Test/SingleElementPlanarTests.hxx new file mode 100755 index 000000000..3fd24854f --- /dev/null +++ b/src/INTERP_KERNEL/Test/SingleElementPlanarTests.hxx @@ -0,0 +1,110 @@ +#ifndef __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ +#define __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ + +#include "InterpolationPlanarTestSuite.hxx" +#include "PolygonAlgorithms.txx" + + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting simple meshes having only one planar element each. + * This serves mainly to verify that the volume calculations between elements is correct. + * + */ + class SingleElementPlanarTests : public InterpolationPlanarTestSuite + { + CPPUNIT_TEST_SUITE( SingleElementPlanarTests ); + + CPPUNIT_TEST( diamondsBasic ); + CPPUNIT_TEST( tangentDiamonds ); + CPPUNIT_TEST( tangentSquares ); + CPPUNIT_TEST( diamondsSharingVertex1 ); + CPPUNIT_TEST( identicalSquares ); + CPPUNIT_TEST( squareAndDiamondBasic ); + CPPUNIT_TEST( squareAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical ); + CPPUNIT_TEST( quadranglesCritical ); + CPPUNIT_TEST( quadrangleAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical2 ); + CPPUNIT_TEST( hexagonsCritical1 ); + CPPUNIT_TEST( hexagonsCritical2 ); + CPPUNIT_TEST( squareAndQuadrangleCritical ); + CPPUNIT_TEST( diamondsSharingVertex2 ); + CPPUNIT_TEST( triangleAndDiamondCritical ); + CPPUNIT_TEST( triangleAndSquareBasic ); + CPPUNIT_TEST( trianglesCritical ); + CPPUNIT_TEST( paralellogramsCritical1 ); + CPPUNIT_TEST( paralellogramsCritical2 ); + CPPUNIT_TEST( trianglesTangencyCritical ); + CPPUNIT_TEST( diamondsBasic_Triangulation ); + CPPUNIT_TEST( tangentDiamonds_Triangulation ); + CPPUNIT_TEST( tangentSquares_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex1_Triangulation ); + CPPUNIT_TEST( identicalSquares_Triangulation ); + CPPUNIT_TEST( squareAndDiamondBasic_Triangulation ); + CPPUNIT_TEST( squareAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical_Triangulation ); + CPPUNIT_TEST( quadranglesCritical_Triangulation ); + CPPUNIT_TEST( quadrangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical2_Triangulation ); + CPPUNIT_TEST( hexagonsCritical1_Triangulation ); + CPPUNIT_TEST( hexagonsCritical2_Triangulation ); + CPPUNIT_TEST( squareAndQuadrangleCritical_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex2_Triangulation ); + CPPUNIT_TEST( triangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( triangleAndSquareBasic_Triangulation ); + CPPUNIT_TEST( trianglesCritical_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical1_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical2_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical_Triangulation ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void diamondsBasic(); + void tangentDiamonds(); + void tangentSquares(); + void diamondsSharingVertex1(); + void identicalSquares(); + void squareAndDiamondBasic(); + void squareAndDiamondCritical(); + void diamondsCritical(); + void quadranglesCritical(); + void quadrangleAndDiamondCritical(); + void diamondsCritical2(); + void hexagonsCritical1(); + void hexagonsCritical2(); + void squareAndQuadrangleCritical(); + void diamondsSharingVertex2(); + void triangleAndDiamondCritical(); + void triangleAndSquareBasic(); + void trianglesCritical(); + void paralellogramsCritical1(); + void paralellogramsCritical2(); + void trianglesTangencyCritical(); + void diamondsBasic_Triangulation(); + void tangentDiamonds_Triangulation(); + void tangentSquares_Triangulation(); + void diamondsSharingVertex1_Triangulation(); + void identicalSquares_Triangulation(); + void squareAndDiamondBasic_Triangulation(); + void squareAndDiamondCritical_Triangulation(); + void diamondsCritical_Triangulation(); + void quadranglesCritical_Triangulation(); + void quadrangleAndDiamondCritical_Triangulation(); + void diamondsCritical2_Triangulation(); + void hexagonsCritical1_Triangulation(); + void hexagonsCritical2_Triangulation(); + void squareAndQuadrangleCritical_Triangulation(); + void diamondsSharingVertex2_Triangulation(); + void triangleAndDiamondCritical_Triangulation(); + void triangleAndSquareBasic_Triangulation(); + void trianglesCritical_Triangulation(); + void paralellogramsCritical1_Triangulation(); + void paralellogramsCritical2_Triangulation(); + void trianglesTangencyCritical_Triangulation(); + }; +} +#endif diff --git a/src/INTERP_KERNEL/Test/SingleElementTetraTests.hxx b/src/INTERP_KERNEL/Test/SingleElementTetraTests.hxx index e0a4b7d34..3724209bd 100644 --- a/src/INTERP_KERNEL/Test/SingleElementTetraTests.hxx +++ b/src/INTERP_KERNEL/Test/SingleElementTetraTests.hxx @@ -1,7 +1,7 @@ #ifndef __SINGLE_ELEMENT_TETRA_TESTS_HXX_ #define __SINGLE_ELEMENT_TETRA_TESTS_HXX_ -#include "Interpolation3DTestSuite.hxx" +#include "InterpolationTestSuite.hxx" namespace INTERP_TEST { @@ -10,7 +10,7 @@ namespace INTERP_TEST * the volume calculations between elements is correct. * */ - class SingleElementTetraTests : public Interpolation3DTestSuite + class SingleElementTetraTests : public InterpolationTestSuite<3,3> { CPPUNIT_TEST_SUITE( SingleElementTetraTests ); diff --git a/src/INTERP_KERNEL/Test/TestInterpKernel.cxx b/src/INTERP_KERNEL/Test/TestInterpKernel.cxx index ca60c6961..0e2463620 100644 --- a/src/INTERP_KERNEL/Test/TestInterpKernel.cxx +++ b/src/INTERP_KERNEL/Test/TestInterpKernel.cxx @@ -26,6 +26,9 @@ #include "HexaTests.hxx" #include "BBTreeTest.hxx" #include "RemapperTest.hxx" +#include "MultiElement2DTests.hxx" +#include "SingleElementPlanarTests.hxx" + using namespace INTERP_TEST; // --- Registers the fixture into the 'registry' @@ -36,6 +39,9 @@ CPPUNIT_TEST_SUITE_REGISTRATION( INTERP_TEST::TransformedTriangleIntersectTest ) CPPUNIT_TEST_SUITE_REGISTRATION( INTERP_TEST::TransformedTriangleTest ); CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest); CPPUNIT_TEST_SUITE_REGISTRATION( RemapperTest); +CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests ); + // --- generic Main program from KERNEL_SRC/src/Basics/Test #include "BasicMainTest.hxx"