From 887d0e1efce4f46f68d2596dcd801f02f5c1f99e Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 12 Feb 2013 13:34:55 +0000 Subject: [PATCH] Merge from V6_main 11/02/2013 --- doc/doxygen/Doxyfile_med_user.in | 2 + .../Bases/NormalizedUnstructuredMesh.hxx | 6 + src/INTERP_KERNEL/CMakeLists.txt | 1 + .../InterpKernelGeo2DQuadraticPolygon.cxx | 16 +- src/INTERP_KERNEL/InterpolationOptions.cxx | 16 + src/INTERP_KERNEL/InterpolationOptions.hxx | 23 +- src/INTERP_KERNEL/Makefile.am | 1 + .../PolyhedronIntersectorP0P0.txx | 3 + src/INTERP_KERNEL/SplitterTetra.hxx | 103 +- src/INTERP_KERNEL/SplitterTetra.txx | 99 +- src/INTERP_KERNEL/VolSurfUser.cxx | 138 ++ src/INTERP_KERNEL/VolSurfUser.hxx | 9 + src/MEDCoupling/CMakeLists.txt | 2 + .../MEDCouplingAutoRefCountObjectPtr.hxx | 1 + src/MEDCoupling/MEDCouplingCMesh.cxx | 376 +--- src/MEDCoupling/MEDCouplingCMesh.hxx | 24 +- .../MEDCouplingCurveLinearMesh.cxx | 875 ++++++++ .../MEDCouplingCurveLinearMesh.hxx | 107 + src/MEDCoupling/MEDCouplingDefinitionTime.cxx | 10 + src/MEDCoupling/MEDCouplingDefinitionTime.hxx | 2 + src/MEDCoupling/MEDCouplingExtrudedMesh.cxx | 15 +- src/MEDCoupling/MEDCouplingExtrudedMesh.hxx | 1 + src/MEDCoupling/MEDCouplingField.cxx | 12 + src/MEDCoupling/MEDCouplingField.hxx | 1 + .../MEDCouplingFieldDiscretization.cxx | 54 +- .../MEDCouplingFieldDiscretization.hxx | 3 + src/MEDCoupling/MEDCouplingFieldDouble.cxx | 102 +- src/MEDCoupling/MEDCouplingFieldDouble.hxx | 8 +- .../MEDCouplingGaussLocalization.cxx | 9 + .../MEDCouplingGaussLocalization.hxx | 1 + src/MEDCoupling/MEDCouplingMemArray.cxx | 592 +++-- src/MEDCoupling/MEDCouplingMemArray.hxx | 88 +- src/MEDCoupling/MEDCouplingMemArray.txx | 106 +- src/MEDCoupling/MEDCouplingMesh.cxx | 29 +- src/MEDCoupling/MEDCouplingMesh.hxx | 4 +- src/MEDCoupling/MEDCouplingMultiFields.cxx | 16 + src/MEDCoupling/MEDCouplingMultiFields.hxx | 1 + src/MEDCoupling/MEDCouplingPointSet.cxx | 25 +- src/MEDCoupling/MEDCouplingPointSet.hxx | 10 +- src/MEDCoupling/MEDCouplingRefCountObject.hxx | 3 + src/MEDCoupling/MEDCouplingRemapper.cxx | 8 +- src/MEDCoupling/MEDCouplingStructuredMesh.cxx | 379 ++++ src/MEDCoupling/MEDCouplingStructuredMesh.hxx | 65 + .../MEDCouplingTimeDiscretization.cxx | 59 +- .../MEDCouplingTimeDiscretization.hxx | 8 + src/MEDCoupling/MEDCouplingUMesh.cxx | 1935 ++++++++++------- src/MEDCoupling/MEDCouplingUMesh.hxx | 53 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 34 +- src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 5 +- src/MEDCoupling/Makefile.am | 5 +- .../Test/MEDCouplingBasicsTest1.cxx | 70 +- .../Test/MEDCouplingBasicsTest2.cxx | 5 + .../Test/MEDCouplingBasicsTest3.cxx | 36 +- .../Test/MEDCouplingBasicsTest4.cxx | 25 +- .../Test/MEDCouplingBasicsTest5.cxx | 303 +++ .../Test/MEDCouplingBasicsTest5.hxx | 10 + src/MEDCouplingCorba/CMakeLists.txt | 2 + src/MEDCouplingCorba/Client/CMakeLists.txt | 1 + src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 794 ++++++- src/MEDCoupling_Swig/MEDCouplingCommon.i | 799 ++++--- .../MEDCouplingRemapperTest.py | 33 + src/MEDCoupling_Swig/MEDCouplingTypemaps.i | 163 +- src/MEDLoader/MEDFileData.cxx | 23 + src/MEDLoader/MEDFileData.hxx | 2 + src/MEDLoader/MEDFileField.cxx | 290 ++- src/MEDLoader/MEDFileField.hxx | 36 +- src/MEDLoader/MEDFileMesh.cxx | 1345 +++++++++--- src/MEDLoader/MEDFileMesh.hxx | 120 +- src/MEDLoader/MEDFileMeshElt.hxx | 1 + src/MEDLoader/MEDFileMeshLL.cxx | 147 +- src/MEDLoader/MEDFileMeshLL.hxx | 24 +- src/MEDLoader/SauvMedConvertor.cxx | 3 +- src/MEDLoader/SauvReader.cxx | 6 +- src/MEDLoader/SauvReader.hxx | 1 + src/MEDLoader/SauvUtilities.hxx | 3 +- src/MEDLoader/SauvWriter.hxx | 2 +- src/MEDLoader/Swig/MEDLoaderCommon.i | 79 +- src/MEDLoader/Swig/MEDLoaderTest3.py | 424 +++- src/MEDLoader/Swig/MEDLoaderTypemaps.i | 2 + src/MEDPartitioner/CMakeLists.txt | 42 +- .../MEDPARTITIONER_JointFinder.cxx | 12 +- .../MEDPARTITIONER_MeshCollection.cxx | 489 ++++- .../MEDPARTITIONER_MeshCollection.hxx | 19 +- .../MEDPARTITIONER_MeshCollectionDriver.cxx | 87 +- .../MEDPARTITIONER_MetisGraph.cxx | 12 +- .../MEDPARTITIONER_ParMetisGraph.cxx | 22 +- .../MEDPARTITIONER_ParMetisGraph.hxx | 39 + .../MEDPARTITIONER_ParaDomainSelector.cxx | 1 + src/MEDPartitioner/MEDPARTITIONER_Utils.cxx | 51 + src/MEDPartitioner/MEDPARTITIONER_Utils.hxx | 40 + src/MEDPartitioner/MEDPARTITIONER_metis.c | 55 + src/MEDPartitioner/MEDPARTITIONER_metis.h | 30 + src/MEDPartitioner/Makefile.am | 30 +- src/MEDPartitioner/Test/CMakeLists.txt | 8 +- .../Test/MEDPARTITIONERTest.cxx | 208 +- .../Test/MEDPARTITIONERTest.hxx | 4 + src/MEDPartitioner/Test/Makefile.am | 6 +- src/MEDPartitioner/medpartitioner.cxx | 7 +- src/ParaMEDMEM/ElementLocator.cxx | 8 +- src/ParaMEDMEM/OverlapElementLocator.cxx | 5 +- 100 files changed, 8661 insertions(+), 2708 deletions(-) create mode 100644 src/INTERP_KERNEL/VolSurfUser.cxx create mode 100644 src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx create mode 100644 src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx create mode 100644 src/MEDCoupling/MEDCouplingStructuredMesh.cxx create mode 100644 src/MEDCoupling/MEDCouplingStructuredMesh.hxx create mode 100644 src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx create mode 100644 src/MEDPartitioner/MEDPARTITIONER_metis.c create mode 100644 src/MEDPartitioner/MEDPARTITIONER_metis.h diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in index 7c4a2f768..29b43e3d7 100644 --- a/doc/doxygen/Doxyfile_med_user.in +++ b/doc/doxygen/Doxyfile_med_user.in @@ -119,6 +119,8 @@ FILE_PATTERNS = MEDMEM_GMesh.* \ MEDCouplingUMeshDesc.* \ MEDCouplingPointSet.* \ MEDCouplingCMesh.* \ + MEDCouplingStructuredMesh.* \ + MEDCouplingCurveLinearMesh.* \ MEDCouplingExtrudedMesh.* \ MEDCouplingFieldDouble.* \ MEDCouplingField.* \ diff --git a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx index 3d43cb6d5..07633641c 100644 --- a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx +++ b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx @@ -61,6 +61,12 @@ namespace INTERP_KERNEL NORM_MAXTYPE = 33 } NormalizedCellType; + /// Type describing the different ways in which the hexahedron can be split into tetrahedra. + /// The PLANAR_* policies persume that each face is to be considered planar, while the general + /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra + /// that result from the split. + typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; + class GenericMesh {}; } diff --git a/src/INTERP_KERNEL/CMakeLists.txt b/src/INTERP_KERNEL/CMakeLists.txt index 02d8637bd..ae70ca322 100644 --- a/src/INTERP_KERNEL/CMakeLists.txt +++ b/src/INTERP_KERNEL/CMakeLists.txt @@ -37,6 +37,7 @@ SET(interpkernel_SOURCES InterpKernelMeshQuality.cxx InterpKernelCellSimplify.cxx InterpKernelMatrixTools.cxx + VolSurfUser.cxx Bases/InterpKernelException.cxx Geometric2D/InterpKernelGeo2DAbstractEdge.cxx Geometric2D/InterpKernelGeo2DBounds.cxx diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index b0ee4f1c2..143bef282 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -29,6 +29,7 @@ #include "NormalizedUnstructuredMesh.hxx" #include +#include #include #include #include @@ -1144,7 +1145,12 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: std::list retPolsUnderContruction; std::list edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end()); std::map > pol1ZipConsumed; - while(!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty()) + std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0; + for(std::list::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++) + nbOfTurn+=(*itMNT)->size(); + maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn; + nbOfTurn=0; + while(nbOfTurn::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();) { @@ -1206,6 +1212,13 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: retPolsUnderContruction.push_back(tmp); pol1Zip.erase(pol1Zip.begin()); } + nbOfTurn++; + } + if(nbOfTurn==maxNbOfTurn) + { + std::ostringstream oss; oss << "Error during reconstruction of residual of cell ! It appears that either source or/and target mesh is/are not conform !"; + oss << " Number of turns is = " << nbOfTurn << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } for(std::list::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++) { @@ -1215,7 +1228,6 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) delete *it6; delete *it1; - it1=retPolsUnderContruction.erase(it1); } } } diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx index 94ab498ff..87f77ab0f 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.cxx +++ b/src/INTERP_KERNEL/InterpolationOptions.cxx @@ -66,6 +66,22 @@ const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_ const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_48_STR[]="GENERAL_48"; +void INTERP_KERNEL::InterpolationOptions::init() +{ + _print_level=0; + _intersection_type=Triangulation; + _precision=1e-12; + _median_plane=DFT_MEDIAN_PLANE; + _do_rotate=true; + _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; + _bounding_box_adjustment_abs=0.; + _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; + _orientation=0; + _measure_abs=true; + _splitting_policy=PLANAR_FACE_5; + _P1P0_bary_method=false; +} + std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const { if(_intersection_type==INTERP_KERNEL::Triangulation) diff --git a/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/INTERP_KERNEL/InterpolationOptions.hxx index 6ba269bb7..e8daeba44 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.hxx +++ b/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -22,17 +22,13 @@ #define __INTERPOLATIONOPTIONS_HXX__ #include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" #include namespace INTERP_KERNEL { typedef enum { Triangulation, Convex, Geometric2D, PointLocator } IntersectionType; - /// Type describing the different ways in which the hexahedron can be split into tetrahedra. - /// The PLANAR_* policies persume that each face is to be considered planar, while the general - /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra - /// that result from the split. - typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; /*! * \class InterpolationOptions @@ -101,21 +97,8 @@ namespace INTERP_KERNEL std::string filterInterpolationMethod(const std::string& meth) const; - void init() - { - _print_level=0; - _intersection_type=Triangulation; - _precision=1e-12; - _median_plane=DFT_MEDIAN_PLANE; - _do_rotate=true; - _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; - _bounding_box_adjustment_abs=0.; - _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; - _orientation=0; - _measure_abs=true; - _splitting_policy=GENERAL_48; - _P1P0_bary_method=false; - } + void init(); + bool setInterpolationOptions(long print_level, std::string intersection_type, double precision, diff --git a/src/INTERP_KERNEL/Makefile.am b/src/INTERP_KERNEL/Makefile.am index 25258d67c..a21327824 100644 --- a/src/INTERP_KERNEL/Makefile.am +++ b/src/INTERP_KERNEL/Makefile.am @@ -218,6 +218,7 @@ dist_libinterpkernel_la_SOURCES = \ TranslationRotationMatrix.cxx \ TetraAffineTransform.cxx \ CellModel.cxx \ + VolSurfUser.cxx \ UnitTetraIntersectionBary.cxx \ InterpolationOptions.cxx \ DirectedBoundingBox.cxx \ diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx index ba5ea83b8..e3a71c91e 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx @@ -84,7 +84,10 @@ namespace INTERP_KERNEL { double volume = 0.; for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { volume += (*iter)->intersectSourceCell(*iterCellS); + (*iter)->clearVolumesCache(); + } if(volume!=0.) res[targetCell].insert(std::make_pair(OTT::indFC(*iterCellS), volume)); } diff --git a/src/INTERP_KERNEL/SplitterTetra.hxx b/src/INTERP_KERNEL/SplitterTetra.hxx index d535b9c37..a58828ccc 100644 --- a/src/INTERP_KERNEL/SplitterTetra.hxx +++ b/src/INTERP_KERNEL/SplitterTetra.hxx @@ -26,14 +26,113 @@ #include "InterpKernelHashMap.hxx" #include "VectorUtils.hxx" -#include -#include #include +#include +#include #include #include namespace INTERP_KERNEL { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + + static const int SPLIT_NODES_5[20] = /* WHY not all well oriented ???? */ + { + 0, 1, 5, 2, + 0, 4, 5, 7, + 0, 3, 7, 2, + 5, 6, 7, 2, + 0, 2, 5, 7 + }; + + static const int SPLIT_NODES_5_WO[20] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ + { + 0, 5, 1, 2, + 0, 4, 5, 7, + 0, 3, 7, 2, + 5, 7, 6, 2, + 0, 5, 2, 7 + }; + + static const int SPLIT_NODES_6[24] = /* WHY all badly oriented ???? */ + { + 0, 1, 5, 6, + 0, 2, 1, 6, + 0, 5, 4, 6, + 0, 4, 7, 6, + 0, 3, 2, 6, + 0, 7, 3, 6 + }; + + static const int SPLIT_NODES_6_WO[24] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ + { + 0, 5, 1, 6, + 0, 1, 2, 6, + 0, 4, 5, 6, + 0, 7, 4, 6, + 0, 2, 3, 6, + 0, 3, 7, 6 + }; + + // Each sub-node is the barycenter of 4 other nodes. + // For the faces, these are on the orignal mesh. + // For the barycenter, the four face sub-nodes are used. + static const int GENERAL_24_SUB_NODES[28] = + { + 0,1,4,5,// sub-node 8 (face) + 0,1,2,3,// sub-node 9 (face) + 0,3,4,7,// sub-node 10 (face) + 1,2,5,6,// sub-node 11 (face) + 4,5,6,7,// sub-node 12 (face) + 2,3,6,7,// sub-node 13 (face) + 8,9,10,11// sub-node 14 (cell) + }; + + static const int TETRA_EDGES_GENERAL_24[48] = + { + // face with center 8 + 0,1, + 1,5, + 5,4, + 4,0, + // face with center 9 + 0,1, + 1,2, + 2,3, + 3,0, + // face with center 10 + 0,4, + 4,7, + 7,3, + 3,0, + // face with center 11 + 1,5, + 5,6, + 6,2, + 2,1, + // face with center 12 + 5,6, + 6,7, + 7,4, + 4,5, + // face with center 13 + 2,6, + 6,7, + 7,3, + 3,2 + }; + /** * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. * diff --git a/src/INTERP_KERNEL/SplitterTetra.txx b/src/INTERP_KERNEL/SplitterTetra.txx index e36dd0ae5..61b2854d6 100644 --- a/src/INTERP_KERNEL/SplitterTetra.txx +++ b/src/INTERP_KERNEL/SplitterTetra.txx @@ -1029,30 +1029,7 @@ namespace INTERP_KERNEL */ template void SplitterTetra2::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - // Schema according to which the splitting is performed. - // Each line represents one tetrahedron. The numbering is as follows : - // - // 7 ------ 6 - // /| /| - // / | / | - // 3 ------ 2 | - // | | | | - // | | | | - // | 4-----|- 5 - // | / | / - // 0 ------ 1 - - - static const int SPLIT_NODES_5[20] = - { - 0, 1, 5, 2, - 0, 4, 5, 7, - 0, 3, 7, 2, - 5, 6, 7, 2, - 0, 2, 5, 7 - }; - + { // create tetrahedra for(int i = 0; i < 5; ++i) { @@ -1078,29 +1055,6 @@ namespace INTERP_KERNEL template void SplitterTetra2::sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) { - // Schema according to which the splitting is performed. - // Each line represents one tetrahedron. The numbering is as follows : - // - // 7 ------ 6 - // /| /| - // / | / | - // 3 ------ 2 | - // | | | | - // | | | | - // | 4-----|- 5 - // | / | / - // 0 ------ 1 - - static const int SPLIT_NODES_6[24] = - { - 0, 1, 5, 6, - 0, 2, 1, 6, - 0, 5, 4, 6, - 0, 4, 7, 6, - 0, 3, 2, 6, - 0, 7, 3, 6 - }; - for(int i = 0; i < 6; ++i) { const double* nodes[4]; @@ -1128,39 +1082,6 @@ namespace INTERP_KERNEL // The two nodes of the original mesh cell used in each tetrahedron. // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes - static const int TETRA_EDGES[48] = - { - // face with center 9 - 0,1, - 1,5, - 5,4, - 4,0, - // face with center 10 - 0,1, - 1,2, - 2,3, - 3,0, - // face with center 11 - 0,4, - 4,7, - 7,3, - 3,0, - // face with center 12 - 1,5, - 5,6, - 6,2, - 2,1, - // face with center 13 - 5,6, - 6,7, - 7,4, - 4,5, - // face with center 14 - 2,6, - 6,7, - 7,3, - 3,2 - }; // nodes to use for tetrahedron const double* nodes[4]; @@ -1177,8 +1098,8 @@ namespace INTERP_KERNEL for(int j = 0; j < 4; ++j) { const int row = 4*(faceCenterNode - 8) + j; - conn[2] = TETRA_EDGES[2*row]; - conn[3] = TETRA_EDGES[2*row + 1]; + conn[2] = TETRA_EDGES_GENERAL_24[2*row]; + conn[3] = TETRA_EDGES_GENERAL_24[2*row + 1]; nodes[2] = getCoordsOfSubNode(conn[2]); nodes[3] = getCoordsOfSubNode(conn[3]); @@ -1341,20 +1262,6 @@ namespace INTERP_KERNEL { case GENERAL_24: { - // Each sub-node is the barycenter of 4 other nodes. - // For the faces, these are on the orignal mesh. - // For the barycenter, the four face sub-nodes are used. - static const int GENERAL_24_SUB_NODES[28] = - { - 0,1,4,5,// sub-node 9 (face) - 0,1,2,3,// sub-node 10 (face) - 0,3,4,7,// sub-node 11 (face) - 1,2,5,6,// sub-node 12 (face) - 4,5,6,7,// sub-node 13 (face) - 2,3,6,7,// sub-node 14 (face) - 8,9,10,11// sub-node 15 (cell) - }; - for(int i = 0; i < 7; ++i) { double* barycenter = new double[3]; diff --git a/src/INTERP_KERNEL/VolSurfUser.cxx b/src/INTERP_KERNEL/VolSurfUser.cxx new file mode 100644 index 000000000..288382500 --- /dev/null +++ b/src/INTERP_KERNEL/VolSurfUser.cxx @@ -0,0 +1,138 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "VolSurfUser.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include +#include +#include + +namespace INTERP_KERNEL +{ + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception) + { + double dx=pt1Seg2[0]-pt0Seg2[0],dy=pt1Seg2[1]-pt0Seg2[1]; + double norm=sqrt(dx*dx+dy*dy); + if(norm==0.) + return std::numeric_limits::max(); + dx/=norm; dy/=norm; + double dx2=pt[0]-pt0Seg2[0],dy2=pt[1]-pt0Seg2[1]; + double dotP=(dx2*dx+dy2*dy); + if(dotP<0. || dotP>norm) + return std::numeric_limits::max(); + double x=pt0Seg2[0]+dotP*dx,y=pt0Seg2[1]+dotP*dy; + return (x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1]); + } + + double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception) + { + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(pt0Tri3,pt1Tri3,pt2Tri3,matrix)) + return std::numeric_limits::max(); + double xy0[2],xy1[2],xy2[2],xy[2]; xy0[0]=0.; xy0[1]=0.; + xy1[0]=matrix[0]*pt1Tri3[0]+matrix[1]*pt1Tri3[1]+matrix[2]*pt1Tri3[2]+matrix[3]; xy1[1]=0.; + xy2[0]=matrix[0]*pt2Tri3[0]+matrix[1]*pt2Tri3[1]+matrix[2]*pt2Tri3[2]+matrix[3]; + xy2[1]=matrix[4]*pt2Tri3[0]+matrix[5]*pt2Tri3[1]+matrix[6]*pt2Tri3[2]+matrix[7]; + xy[0]=matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3]; + xy[1]=matrix[4]*pt[0]+matrix[5]*pt[1]+matrix[6]*pt[2]+matrix[7]; + double z=matrix[8]*pt[0]+matrix[9]*pt[1]+matrix[10]*pt[2]+matrix[11]; + double ret=std::numeric_limits::max(); + int nbOfHint=0; + if(xy[0]>0. && xy[0]::max()) + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } + tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy2,xy0);//distance pt to edge [pt2Tri3,pt0Tri3] + if(tmp!=std::numeric_limits::max()) + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } + if(nbOfHint==3) + ret=std::min(ret,fabs(z)); + return ret; + } + + double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception) + { + std::size_t nbOfEdges=std::distance(connOfPolygonBg,connOfPolygonEnd); + if(nbOfEdges<3) + throw INTERP_KERNEL::Exception("DistanceFromPtToPolygonInSpaceDim3 : trying to compute a distance to a polygon containing less than 3 edges !"); + double baryOfNodes[3]={0.,0.,0.}; + for(std::size_t i=0;i(),1./((double)nbOfEdges))); + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix)) + return std::numeric_limits::max(); + INTERP_KERNEL::AutoPtr ptXY=new double[2*nbOfEdges]; ptXY[0]=0.; ptXY[1]=0.; + ptXY[2]=matrix[0]*coords[3*connOfPolygonBg[1]]+matrix[1]*coords[3*connOfPolygonBg[1]+1]+matrix[2]*coords[3*connOfPolygonBg[1]+2]+matrix[3]; ptXY[3]=0.; + for(std::size_t i=2;i::max(); + std::size_t nbOfHint=0; + for(std::size_t i=0;i::max()) + { ret=std::min(ret,sqrt(z*z+tmp)); nbOfHint++; } + } + if(nbOfHint==nbOfEdges) + ret=std::min(ret,fabs(z)); + return ret; + } + + /*! + * \param [out] matrix contain a dense matrix of size 12 with 3 rows containing each 4 colums. This matrix is the reduction of 4x4 matrix but the last + * line containing [0,0,0,1] is omitted. + */ + bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *p0, const double *p1, const double *p2, double *matrix) + { + double norm=sqrt((p1[0]-p0[0])*(p1[0]-p0[0])+(p1[1]-p0[1])*(p1[1]-p0[1])+(p1[2]-p0[2])*(p1[2]-p0[2])); + double c=(p1[0]-p0[0])/norm; + double s=sqrt(1-c*c); + double y=p1[2]-p0[2],z=p0[1]-p1[1]; + norm=sqrt(y*y+z*z); + if(norm!=0.) + { y/=norm; z/=norm; } + double r0[9]={c,-z*s,y*s, + z*s,y*y*(1-c)+c,y*z*(1-c), + -y*s,z*y*(1-c),z*z*(1-c)+c}; + // 2nd rotation matrix + double x=p2[0]-p0[0]; + y=p2[1]-p0[1]; z=p2[2]-p0[2]; + double y1=x*r0[3]+y*r0[4]+z*r0[5],z1=x*r0[6]+y*r0[7]+z*r0[8]; + c=y1/sqrt(y1*y1+z1*z1); + s=sqrt(1.-c*c); + // + std::copy(r0,r0+3,matrix); + matrix[4]=c*r0[3]-s*r0[6]; matrix[5]=c*r0[4]-s*r0[7]; matrix[6]=c*r0[5]-s*r0[8]; + matrix[8]=s*r0[3]+c*r0[6]; matrix[9]=s*r0[4]+c*r0[7]; matrix[10]=s*r0[5]+c*r0[8]; + matrix[3]=-p0[0]*matrix[0]-p0[1]*matrix[1]-p0[2]*matrix[2]; + matrix[7]=-p0[0]*matrix[4]-p0[1]*matrix[5]-p0[2]*matrix[6]; + matrix[11]=-p0[0]*matrix[8]-p0[1]*matrix[9]-p0[2]*matrix[10]; + return true; + } +} + diff --git a/src/INTERP_KERNEL/VolSurfUser.hxx b/src/INTERP_KERNEL/VolSurfUser.hxx index e6f877bf4..20899dc59 100644 --- a/src/INTERP_KERNEL/VolSurfUser.hxx +++ b/src/INTERP_KERNEL/VolSurfUser.hxx @@ -21,6 +21,7 @@ #ifndef __VOLSURFUSER_HXX__ #define __VOLSURFUSER_HXX__ +#include "InterpKernelException.hxx" #include "NormalizedUnstructuredMesh.hxx" namespace INTERP_KERNEL @@ -36,6 +37,14 @@ namespace INTERP_KERNEL template void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); + + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2) throw(INTERP_KERNEL::Exception); + + double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception); + + double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception); + + bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix); } #endif diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index ad1c6fa2b..a8d57ffb9 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -36,6 +36,8 @@ SET(medcoupling_SOURCES MEDCouplingMemArray.cxx MEDCouplingTimeLabel.cxx MEDCouplingCMesh.cxx + MEDCouplingCurveLinearMesh.cxx + MEDCouplingStructuredMesh.cxx MEDCouplingTimeDiscretization.cxx MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx index fc0c0f4e9..563a5838f 100644 --- a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx +++ b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx @@ -41,6 +41,7 @@ namespace ParaMEDMEM const T& operator*() const { return *_ptr; } operator T *() { return _ptr; } operator const T *() const { return _ptr; } + T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; } private: void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); } void destroyPtr() { if(_ptr) _ptr->decrRef(); } diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 2276b4d28..1ae822817 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -19,7 +19,6 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingCMesh.hxx" -#include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" @@ -34,7 +33,7 @@ MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) { } -MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other) +MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy) { if(deepCopy) { @@ -107,6 +106,18 @@ void MEDCouplingCMesh::updateTime() const updateTimeWith(*_z_array); } +std::size_t MEDCouplingCMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + std::set s; + s.insert(_x_array); s.insert(_y_array); s.insert(_z_array); + s.erase(NULL); + for(std::set::const_iterator it=s.begin();it!=s.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + return MEDCouplingStructuredMesh::getHeapMemorySize()+ret; +} + /*! * This method copyies all tiny strings from other (name and components name). * @throw if other and this have not same mesh type. @@ -116,7 +127,7 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I const MEDCouplingCMesh *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingMesh::copyTinyStringsFrom(other); + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); if(_x_array && otherC->_x_array) _x_array->copyStringInfoFrom(*otherC->_x_array); if(_y_array && otherC->_y_array) @@ -307,35 +318,11 @@ void MEDCouplingCMesh::getSplitNodeValues(int *res) const } } -int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitCellValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const +void MEDCouplingCMesh::getNodeGridStructure(int *res) const { - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitNodeValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res) -{ - int work=nodeId; - for(int i=spaceDim-1;i>=0;i--) - { - int pos=work/split[i]; - work=work%split[i]; - res[i]=pos; - } + int meshDim=getMeshDimension(); + for(int i=0;igetNbOfElems(); } int MEDCouplingCMesh::getSpaceDimension() const @@ -355,92 +342,6 @@ int MEDCouplingCMesh::getMeshDimension() const return getSpaceDimension(); } -INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const -{ - switch(getMeshDimension()) - { - case 3: - return INTERP_KERNEL::NORM_HEXA8; - case 2: - return INTERP_KERNEL::NORM_QUAD4; - case 1: - return INTERP_KERNEL::NORM_SEG2; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); - } -} - -std::set MEDCouplingCMesh::getAllGeoTypes() const -{ - INTERP_KERNEL::NormalizedCellType ret; - switch(getMeshDimension()) - { - case 3: - ret=INTERP_KERNEL::NORM_HEXA8; - break; - case 2: - ret=INTERP_KERNEL::NORM_QUAD4; - break; - case 1: - ret=INTERP_KERNEL::NORM_SEG2; - break; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !"); - } - std::set ret2; - ret2.insert(ret); - return ret2; -} - -int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=getNumberOfCells(); - int dim=getMeshDimension(); - switch(type) - { - case INTERP_KERNEL::NORM_HEXA8: - if(dim==3) - return ret; - case INTERP_KERNEL::NORM_QUAD4: - if(dim==2) - return ret; - case INTERP_KERNEL::NORM_SEG2: - if(dim==1) - return ret; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); - } - return 0; -} - -void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int spaceDim=getSpaceDimension(); - int tmpCell[3],tmpNode[3]; - getSplitCellValues(tmpCell); - getSplitNodeValues(tmpNode); - int tmp2[3]; - GetPosFromId(cellId,spaceDim,tmpCell,tmp2); - switch(spaceDim) - { - case 1: - conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); - break; - case 2: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); - break; - case 3: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); - }; -} - void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) { int tmp[3]; @@ -561,107 +462,6 @@ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArray declareAsNew(); } -/*! - * See MEDCouplingUMesh::getDistributionOfTypes for more information - */ -std::vector MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) -{ - //only one type of cell - std::vector ret(3); - ret[0]=getTypeOfCell(0); - ret[1]=getNumberOfCells(); - ret[2]=0; //ret[3*k+2]==0 because it has no sense here - return ret; -} - -/*! - * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information - */ -DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - if(sz!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); - - int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); - if(code[2]==-1) - { - if(code[1]==nbCells) - return 0; - else - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); - } - else - { - if(code[2]<-1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); - if(code[2]>=(int)idsPerType.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); - return idsPerType[code[2]]->deepCpy(); - } -} - -/*! - * See MEDCouplingUMesh::splitProfilePerType for more information - */ -void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - int nbCells=getNumberOfCells(); - code.resize(3); - code[0]=(int)getTypeOfCell(0); - code[1]=nbCells; - code[2]=0; - idsInPflPerType.push_back(profile->deepCpy()); - idsPerType.push_back(profile->deepCpy()); -} - -MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) -{ - int spaceDim=getSpaceDimension(); - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim); - DataArrayDouble *coords=getCoordinatesAndOwner(); - ret->setCoords(coords); - coords->decrRef(); - switch(spaceDim) - { - case 1: - fill1DUnstructuredMesh(ret); - break; - case 2: - fill2DUnstructuredMesh(ret); - break; - case 3: - fill3DUnstructuredMesh(ret); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); - }; - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPart(start,end); - um->decrRef(); - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; -} - -DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) -{ - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !"); -} - void MEDCouplingCMesh::getBoundingBox(double *bbox) const { int dim=getSpaceDimension(); @@ -685,7 +485,7 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const std::string name="MeasureOfMesh_"; name+=getName(); int nbelem=getNumberOfCells(); - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS); + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); field->setName(name.c_str()); DataArrayDouble* array=DataArrayDouble::New(); array->alloc(nbelem,1); @@ -693,6 +493,7 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const field->setArray(array) ; array->decrRef(); field->setMesh(const_cast(this)); + field->synchronizeTimeWithMesh(); int tmp[3]; getSplitCellValues(tmp); int dim=getSpaceDimension(); @@ -721,23 +522,6 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) cons //return 0; } -MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - array->alloc(nbOfCells,3); - double *vals=array->getPointer(); - for(int i=0;isetArray(array); - array->decrRef(); - ret->setMesh(this); - return ret; -} - int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const { int dim=getSpaceDimension(); @@ -871,95 +655,6 @@ void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INT throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); } -void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c=getCoordsAt(0); - int nbOfCells=c->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(nbOfCells+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(3*nbOfCells,1); - ci[0]=0; - int *cp=conn->getPointer(); - for(int i=0;isetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - -void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(5*n1*n2,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;jsetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - -void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - const DataArrayDouble *c3=getCoordsAt(2); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - int n3=c3->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2*n3+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(9*n1*n2*n3,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;ksetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const { int it,order; @@ -1041,7 +736,36 @@ void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, con void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) { - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !"); + std::ostringstream extent; + DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; } + else + { extent << "0 0 "; } + } + ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n"; + ofs << " \n"; + ofs << " \n" << pointData << std::endl; + ofs << " \n"; + ofs << " \n" << cellData << std::endl; + ofs << " \n"; + ofs << " \n"; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + thisArr[i]->writeVTK(ofs,8,"Array"); + else + { + MEDCouplingAutoRefCountObjectPtr coo=DataArrayDouble::New(); coo->alloc(1,1); + coo->setIJ(0,0,0.); + coo->writeVTK(ofs,8,"Array"); + } + } + ofs << " \n"; + ofs << " \n"; + ofs << " \n"; } std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index 39407ebb6..e1f25b51a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -22,14 +22,14 @@ #define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ #include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" +#include "MEDCouplingStructuredMesh.hxx" namespace ParaMEDMEM { class DataArrayDouble; class MEDCouplingUMesh; - class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingMesh + class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingStructuredMesh { public: static MEDCouplingCMesh *New(); @@ -37,6 +37,7 @@ namespace ParaMEDMEM MEDCouplingMesh *deepCpy() const; MEDCouplingCMesh *clone(bool recDeepCpy) const; void updateTime() const; + std::size_t getHeapMemorySize() const; MEDCouplingMeshType getType() const { return CARTESIAN; } void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); @@ -52,13 +53,6 @@ namespace ParaMEDMEM int getNumberOfNodes() const; int getSpaceDimension() const; int getMeshDimension() const; - int getCellIdFromPos(int i, int j, int k) const; - int getNodeIdFromPos(int i, int j, int k) const; - static void GetPosFromId(int nodeId, int spaceDim, const int *split, int *res); - INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - std::set getAllGeoTypes() const; - int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - void getNodeIdsOfCell(int cellId, std::vector& conn) const; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; @@ -69,17 +63,9 @@ namespace ParaMEDMEM const DataArrayDouble *coordsY=0, const DataArrayDouble *coordsZ=0); // tools - std::vector getDistributionOfTypes() const throw(INTERP_KERNEL::Exception); - DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); - void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); void getBoundingBox(double *bbox) const; MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCouplingFieldDouble *buildOrthogonalField() const; int getCellContainingPoint(const double *pos, double eps) const; void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); @@ -88,12 +74,10 @@ namespace ParaMEDMEM DataArrayDouble *getCoordinatesAndOwner() const; DataArrayDouble *getBarycenterAndOwner() const; void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const; - void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const; - void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const; //some useful methods void getSplitCellValues(int *res) const; void getSplitNodeValues(int *res) const; + void getNodeGridStructure(int *res) const; //serialisation-unserialization void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx new file mode 100644 index 000000000..a35c5b9dd --- /dev/null +++ b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx @@ -0,0 +1,875 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "MEDCouplingCurveLinearMesh.hxx" +#include "MEDCouplingPointSet.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include "VolSurfUser.txx" +#include "PointLocatorAlgos.txx" + +#include +#include +#include +#include + +using namespace ParaMEDMEM; + +MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh():_coords(0),_structure(0) +{ +} + +MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_structure(other._structure) +{ + if(deepCopy) + { + if((const DataArrayDouble *)other._coords) + _coords=other._coords->deepCpy(); + } + else + _coords=other._coords; +} + +MEDCouplingCurveLinearMesh::~MEDCouplingCurveLinearMesh() +{ +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New() +{ + return new MEDCouplingCurveLinearMesh; +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New(const char *meshName) +{ + MEDCouplingCurveLinearMesh *ret=new MEDCouplingCurveLinearMesh; + ret->setName(meshName); + return ret; +} + +MEDCouplingMesh *MEDCouplingCurveLinearMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingCurveLinearMesh(*this,recDeepCpy); +} + +void MEDCouplingCurveLinearMesh::updateTime() const +{ + if((const DataArrayDouble *)_coords) + updateTimeWith(*_coords); +} + +std::size_t MEDCouplingCurveLinearMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_structure.capacity()*sizeof(int); + if((const DataArrayDouble *)_coords) + ret+=_coords->getHeapMemorySize(); + return MEDCouplingStructuredMesh::getHeapMemorySize()+ret; +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingCurveLinearMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); + if((DataArrayDouble *)_coords && (const DataArrayDouble *)otherC->_coords) + _coords->copyStringInfoFrom(*otherC->_coords); +} + +bool MEDCouplingCurveLinearMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingCurveLinearMesh !"; + return false; + } + if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + std::ostringstream oss; oss.precision(15); + if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) + { + oss << "Only one CurveLinearMesh between the two this and other has its coordinates defined !"; + reason=oss.str(); + return false; + } + if((const DataArrayDouble *)_coords) + { + if(!_coords->isEqualIfNotWhy(*(otherC->_coords),prec,reason)) + { + oss << "Coordinates DataArrayDouble of differ :"; + reason.insert(0,oss.str()); + return false; + } + if(_structure!=otherC->_structure) + { reason="CurveLinearMesh structures differ !"; return false; } + } + return true; +} + +bool MEDCouplingCurveLinearMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) + return false; + if((const DataArrayDouble *)_coords) + { + if(!_coords->isEqualWithoutConsideringStr(*(otherC->_coords),prec)) + return false; + if(_structure!=otherC->_structure) + return false; + } + return true; +} + +void MEDCouplingCurveLinearMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalWith : Meshes are not the same !"); +} + +/*! + * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCurveLinearMesh instance too). + * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCurveLinearMesh, 'this' and 'other' are the same ! + */ +void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !"); +} + +void MEDCouplingCurveLinearMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + std::size_t sz=_structure.size(),i=0,nbOfNodes=1; + if(sz<1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : structure should have a lgth of size 1 at least !"); + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,i++) + { + if((*it)<1) + { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : At pos #" << i << " of structure value is " << *it << "should be >= 1 !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + nbOfNodes*=*it; + } + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not set !"); + if(!_coords->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not allocated !"); + if(_coords->getNumberOfComponents()<1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array should have >= 1 components !"); + if(_coords->getNumberOfTuples()!=(int)nbOfNodes) + { + std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : structure said that number of nodes should be equal to " << nbOfNodes << " but number of tuples in array is equal to " << _coords->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCouplingCurveLinearMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); +} + +void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + +int MEDCouplingCurveLinearMesh::getNumberOfCells() const +{ + checkCoherency(); + std::size_t nbOfCells=1,i=0; + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,i++) + nbOfCells*=(*it)-1; + return (int)nbOfCells; +} + +int MEDCouplingCurveLinearMesh::getNumberOfNodes() const +{ + checkCoherency(); + std::size_t nbOfNodes=1; + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++) + nbOfNodes*=(*it); + return (int)nbOfNodes; +} + +void MEDCouplingCurveLinearMesh::getSplitCellValues(int *res) const +{ + int meshDim=getMeshDimension(); + for(int l=0;lgetNumberOfComponents(); +} + +int MEDCouplingCurveLinearMesh::getMeshDimension() const +{ + return (int)_structure.size(); +} + +void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) +{ + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCoordinatesOfNode : Coordinates not set !"); + int nbOfCompo=_coords->getNumberOfComponents(); + if(nodeId>=0 && nodeId<_coords->getNumberOfTuples()) + coo.insert(coo.end(),_coords->begin()+nodeId*nbOfCompo,_coords->begin()+(nodeId+1)*nbOfCompo); + else + { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::getCoordinatesOfNode : nodeId has to be in [0," << _coords->getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } +} + +std::string MEDCouplingCurveLinearMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "Curve linear mesh with name : \"" << getName() << "\"\n"; + ret << "Description of mesh : \"" << getDescription() << "\"\n"; + int tmpp1,tmpp2; + double tt=getTime(tmpp1,tmpp2); + ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; + ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; + ret << "The nodal stucture of curve linear mesh is : ["; + std::copy(_structure.begin(),_structure.end(),std::ostream_iterator(ret,",")); ret << "]\n"; + ret << "The coords array is this : "; + if((const DataArrayDouble *)_coords) + _coords->reprZipWithoutNameStream(ret); + else + ret << "no array specified !"; + return ret.str(); +} + +std::string MEDCouplingCurveLinearMesh::advancedRepr() const +{ + return simpleRepr(); +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() throw(INTERP_KERNEL::Exception) +{ + return _coords; +} + +const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const throw(INTERP_KERNEL::Exception) +{ + return _coords; +} + +void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception) +{ + if(coords!=(const DataArrayDouble *)_coords) + { + _coords=const_cast(coords); + if(coords) + coords->incrRef(); + declareAsNew(); + } +} + +void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception) +{ + _structure.resize(0); + _structure.insert(_structure.end(),gridStructBg,gridStructEnd); +} + +std::vector MEDCouplingCurveLinearMesh::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +{ + return _structure; +} + +void MEDCouplingCurveLinearMesh::getBoundingBox(double *bbox) const +{ + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBoundingBox : Coordinates not set !"); + _coords->getMinMaxPerComponent(bbox); +} + +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureField(bool isAbs) const +{ + checkCoherency(); + int meshDim=getMeshDimension(); + std::string name="MeasureOfMesh_"; name+=getName(); + MEDCouplingAutoRefCountObjectPtr field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + field->setName(name.c_str()); field->setMesh(const_cast(this)); field->synchronizeTimeWithMesh(); + switch(meshDim) + { + case 3: + { getMeasureFieldMeshDim3(isAbs,field); return field.retn(); } + case 2: + { getMeasureFieldMeshDim2(isAbs,field); return field.retn(); } + case 1: + { getMeasureFieldMeshDim1(isAbs,field); return field.retn(); } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureField : mesh dimension must be in [1,2,3] !"); + } +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbnodes=getNumberOfNodes(); + int spaceDim=getSpaceDimension(); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + if(nbnodes==0) + { arr->alloc(0,1); return; } + if(spaceDim==1) + { + arr->alloc(nbnodes-1,1); + std::transform(_coords->begin()+1,_coords->end(),_coords->begin(),arr->getPointer(),std::minus()); + if(isAbs) + arr->abs(); + } + else + { + MEDCouplingAutoRefCountObjectPtr tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim); + std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus()); + MEDCouplingAutoRefCountObjectPtr tmp2=tmp->magnitude(); field->setArray(tmp2); + } +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + arr->alloc(nbcells,1); + double *pt=arr->getPointer(); + const double *coords=_coords->begin(); + int nX=_structure[0]-1; + int conn[4]; + for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coords,spaceDim); + } + if(isAbs) + arr->abs(); +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + arr->alloc(nbcells,1); + double *pt=arr->getPointer(); + const double *coords=_coords->begin(); + int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); + int nY1=_structure[0]*_structure[1]; + int conn[8]; + for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coords,3); + } + if(isAbs) + arr->abs(); +} + +/*! + * not implemented yet ! + */ +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureFieldOnNode(bool isAbs) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldOnNode : not implemented yet !"); +} + +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::buildOrthogonalField() const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + array->alloc(nbOfCells,3); + double *vals=array->getPointer(); + for(int i=0;isetArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +/// @cond INTERNAL + +namespace ParaMEDMEM +{ + template + class DummyClsMCL + { + public: + static const int MY_SPACEDIM=SPACEDIMM; + static const int MY_MESHDIM=8; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; + // begin + // useless, but for windows compilation ... + const double* getCoordinatesPtr() const { return 0; } + const int* getConnectivityPtr() const { return 0; } + const int* getConnectivityIndexPtr() const { return 0; } + INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; } + // end + }; +} + +/// @endcond + +int MEDCouplingCurveLinearMesh::getCellContainingPoint(const double *pos, double eps) const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + const double *coords=_coords->getConstPointer(); + int nodeId=-1; + _coords->distanceToTuple(pos,pos+spaceDim,nodeId); + if(nodeId<0) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : internal problem 1 !"); + int conn[8]; + int nbOfNodes=getNumberOfNodes(); + if(nbOfNodes==1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : No cells in this !"); + switch(getMeshDimension()) + { + case 1: + if(spaceDim==1) + { + if(nodeId>0) + { + conn[0]=nodeId-1; conn[1]=nodeId; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) + return nodeId-1; + } + if(nodeId >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) + return nodeId; + } + } + case 2: + if(spaceDim==2) + { + int ny=nodeId/_structure[0],nx=nodeId-ny*_structure[0]; + if(nx>0 && ny>0) + { + conn[0]=nx-1+_structure[0]*(ny-1); conn[1]=nx-1+_structure[0]*ny; conn[2]=nx+_structure[0]*ny; conn[3]=nx+_structure[0]*(ny-1); + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx-1+(ny-1)*_structure[0]; + } + if(nx<_structure[0]-1 && ny>0) + { + conn[0]=nx+_structure[0]*(ny-1); conn[1]=nx+_structure[0]*ny; conn[2]=nx+1+_structure[0]*ny; conn[3]=nx+1+_structure[0]*(ny-1); + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx+(ny-1)*_structure[0]; + } + if(nx>0 && ny<_structure[1]-1) + { + conn[0]=nx-1+_structure[0]*ny; conn[1]=nx-1+_structure[0]*(ny+1); conn[2]=nx+_structure[0]*(ny+1); conn[3]=nx+_structure[0]*ny; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx-1+ny*_structure[0]; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1) + { + conn[0]=nx+_structure[0]*ny; conn[1]=nx+_structure[0]*(ny+1); conn[2]=nx+1+_structure[0]*(ny+1); conn[3]=nx+1+_structure[0]*ny; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx+ny*_structure[0]; + } + } + case 3: + { + if(spaceDim==3) + { + int nY=_structure[0]*_structure[1]; + int nz=nodeId/_structure[1]; int ny=(nodeId-nz*nY)/_structure[0]; int nx=(nodeId-nz*nY)-_structure[0]*ny; + if(nx>0 && ny>0 && nz>0) + { + conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+(ny-1)*_structure[0]+(nz-1)*nY; + } + if(nx<_structure[0]-1 && ny>0 && nz>0) + { + conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+(ny-1)*_structure[0]+(nz-1)*nY; + } + if(nx>0 && ny<_structure[1]-1 && nz>0) + { + conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); + conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+ny*_structure[0]+(nz-1)*nY; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz>0) + { + conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); + conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+ny*_structure[0]+(nz-1)*nY; + } + if(nx>0 && ny>0 && nz<_structure[2]-1) + { + conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+(ny-1)*_structure[0]+nz*nY; + } + if(nx<_structure[0]-1 && ny>0 && nz<_structure[2]-1) + { + conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+(ny-1)*_structure[0]+nz*nY; + } + if(nx>0 && ny<_structure[1]-1 && nz<_structure[2]-1) + { + conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); + conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+ny*_structure[0]+nz*nY; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz<_structure[2]-1) + { + conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); + conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+ny*_structure[0]+nz*nY; + } + } + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : mesh dimension managed are 1, 2 or 3 !"); + } +} + +void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vector, double angle) +{ + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : no coordinates set !"); + int spaceDim=getSpaceDimension(); + int nbNodes=_coords->getNumberOfTuples(); + double *coords=_coords->getPointer(); + if(spaceDim==3) + MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords); + else if(spaceDim==2) + MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords); + else + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3"); + _coords->declareAsNew(); + updateTime(); +} + +void MEDCouplingCurveLinearMesh::translate(const double *vector) +{ + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !"); + double *coords=_coords->getPointer(); + int nbNodes=getNumberOfNodes(); + int dim=getSpaceDimension(); + for(int i=0; ideclareAsNew(); + updateTime(); +} + +void MEDCouplingCurveLinearMesh::scale(const double *point, double factor) +{ + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !"); + double *coords=_coords->getPointer(); + int nbNodes=_coords->getNumberOfTuples(); + int dim=_coords->getNumberOfComponents(); + for(int i=0;i()); + std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); + } + _coords->declareAsNew(); + updateTime(); +} + +MEDCouplingMesh *MEDCouplingCurveLinearMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::mergeMyselfWith : not available for CurveLinear Mesh !"); +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getCoordinatesAndOwner() const +{ + DataArrayDouble *ret=const_cast((const DataArrayDouble *)_coords); + if(ret) + ret->incrRef(); + return ret; +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + int nbOfCells=getNumberOfCells(); + ret->alloc(nbOfCells,spaceDim); + ret->copyStringInfoFrom(*getCoords()); + switch(meshDim) + { + case 3: + { getBarycenterAndOwnerMeshDim3(ret); return ret.retn(); } + case 2: + { getBarycenterAndOwnerMeshDim2(ret); return ret.retn(); } + case 1: + { getBarycenterAndOwnerMeshDim1(ret); return ret.retn(); } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwner : mesh dimension must be in [1,2,3] !"); + } +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const +{ + int nbOfCells=getNumberOfCells(); + double *ptToFill=bary->getPointer(); + const double *coor=_coords->getConstPointer(); + if(getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); + int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); + int nY1=_structure[0]*_structure[1]; + int conn[8]; + for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coor,3,ptToFill); + ptToFill+=3; + } +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + double *ptToFill=bary->getPointer(); + const double *coor=_coords->getConstPointer(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); + int nX=_structure[0]-1; + int conn[4]; + for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coor,spaceDim,ptToFill); + ptToFill+=spaceDim; + } +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const +{ + int spaceDim=getSpaceDimension(); + std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),bary->getPointer(),std::plus()); + std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies(),0.5)); +} + +void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !"); +} + +void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const +{ + int it,order; + double time=getTime(it,order); + tinyInfo.clear(); + tinyInfoD.clear(); + littleStrings.clear(); + littleStrings.push_back(getName()); + littleStrings.push_back(getDescription()); + littleStrings.push_back(getTimeUnit()); + // + std::vector littleStrings2; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationStrInformation(littleStrings2); + littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); + // + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfo.push_back((int)_structure.size()); + for(std::vector::const_iterator itt=_structure.begin();itt!=_structure.end();itt++) + tinyInfo.push_back(*itt); + std::vector tinyInfo2; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationIntInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + // + tinyInfoD.push_back(time); +} + +void MEDCouplingCurveLinearMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const +{ + a1->alloc(tinyInfo[2],1); + std::vector tinyInfo2(tinyInfo.begin()+3+tinyInfo[2],tinyInfo.end()); + a2->resizeForUnserialization(tinyInfo2); +} + +void MEDCouplingCurveLinearMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); + a1->alloc((int)_structure.size(),1); + int *ptr=a1->getPointer(); + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,ptr++) + *ptr=(*it); + int sz=0; + if((const DataArrayDouble *)_coords) + if(_coords->isAllocated()) + sz=_coords->getNbOfElems(); + a2=DataArrayDouble::New(); + a2->alloc(sz,1); + if(sz!=0 && (const DataArrayDouble *)_coords) + std::copy(_coords->begin(),_coords->end(),a2->getPointer()); +} + +void MEDCouplingCurveLinearMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings) +{ + setName(littleStrings[0].c_str()); + setDescription(littleStrings[1].c_str()); + setTimeUnit(littleStrings[2].c_str()); + setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); + int sz=tinyInfo[2]; + _structure.resize(sz); + for(int i=0;isz+3) + { + _coords=DataArrayDouble::New(); + std::vector tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end()); + _coords->resizeForUnserialization(tinyInfo2); + std::copy(a2->begin(),a2->end(),_coords->getPointer()); + std::vector littleStrings2(littleStrings.begin()+3,littleStrings.end()); + _coords->finishUnserialization(tinyInfo2,littleStrings2); + } +} + +void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream extent; + int meshDim=(int)_structure.size(); + if(meshDim<=0 || meshDim>3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::writeVTKLL : meshDim invalid ! must be in [1,2,3] !"); + for(int i=0;i<3;i++) + { int val=i\n"; + ofs << " \n"; + ofs << " \n" << pointData << std::endl; + ofs << " \n"; + ofs << " \n" << cellData << std::endl; + ofs << " \n"; + ofs << " \n"; + if(getSpaceDimension()==3) + _coords->writeVTK(ofs,8,"Points"); + else + { + MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); + coo->writeVTK(ofs,8,"Points"); + } + ofs << " \n"; + ofs << " \n"; + ofs << " \n"; +} + +std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) +{ + return std::string("StructuredGrid"); +} diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx new file mode 100644 index 000000000..cab1c6739 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx @@ -0,0 +1,107 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#ifndef __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingStructuredMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + + class MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh + { + public: + static MEDCouplingCurveLinearMesh *New(); + static MEDCouplingCurveLinearMesh *New(const char *meshName); + MEDCouplingMesh *deepCpy() const; + MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; + void updateTime() const; + std::size_t getHeapMemorySize() const; + MEDCouplingMeshType getType() const { return CURVE_LINEAR; } + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + int getNumberOfCells() const; + int getNumberOfNodes() const; + int getSpaceDimension() const; + int getMeshDimension() const; + void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + std::string advancedRepr() const; + DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception); + const DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception); + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception); + std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); + // tools + void getBoundingBox(double *bbox) const; + MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCouplingFieldDouble *buildOrthogonalField() const; + int getCellContainingPoint(const double *pos, double eps) const; + void rotate(const double *center, const double *vector, double angle); + void translate(const double *vector); + void scale(const double *point, double factor); + MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + DataArrayDouble *getCoordinatesAndOwner() const; + DataArrayDouble *getBarycenterAndOwner() const; + void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); + //some useful methods + void getSplitCellValues(int *res) const; + void getSplitNodeValues(int *res) const; + void getNodeGridStructure(int *res) const; + //serialisation-unserialization + void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); + private: + void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const; + void getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const; + void getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const; + private: + MEDCouplingCurveLinearMesh(); + MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCpy); + ~MEDCouplingCurveLinearMesh(); + void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception); + std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _coords; + std::vector _structure; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx b/src/MEDCoupling/MEDCouplingDefinitionTime.cxx index 0d703ce73..8663ca2f2 100644 --- a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx +++ b/src/MEDCoupling/MEDCouplingDefinitionTime.cxx @@ -109,6 +109,11 @@ MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCoupling throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ..."); } +std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySize() const +{ + return 0; +} + bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const { double t1=getStartTime(); @@ -459,6 +464,11 @@ MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector& tiI, std::vector& tiD) const = 0; virtual TypeOfTimeDiscretization getTimeType() const = 0; + std::size_t getHeapMemorySize() const; bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; @@ -142,6 +143,7 @@ namespace ParaMEDMEM public: MEDCouplingDefinitionTime(); MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; void assign(const MEDCouplingDefinitionTime& other); bool isEqual(const MEDCouplingDefinitionTime& other) const; double getTimeResolution() const { return _eps; } diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 663737af5..875889dad 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -64,6 +64,18 @@ MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const return EXTRUDED; } +std::size_t MEDCouplingExtrudedMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_mesh2D) + ret+=_mesh2D->getHeapMemorySize(); + if(_mesh1D) + ret+=_mesh1D->getHeapMemorySize(); + if(_mesh3D_ids) + ret+=_mesh3D_ids->getHeapMemorySize(); + return MEDCouplingMesh::getHeapMemorySize()+ret; +} + /*! * This method copyies all tiny strings from other (name and components name). * @throw if other and this have not same mesh type. @@ -398,8 +410,9 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const int nbOf1DCells=_mesh1D->getNumberOfCells(); int nbOf3DCells=nbOf2DCells*nbOf1DCells; const int *renum=_mesh3D_ids->getConstPointer(); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); + ret->synchronizeTimeWithMesh(); DataArrayDouble *da=DataArrayDouble::New(); da->alloc(nbOf3DCells,1); double *retPtr=da->getPointer(); diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 9dc8122ed..8f9bc9c09 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -39,6 +39,7 @@ namespace ParaMEDMEM static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); static MEDCouplingExtrudedMesh *New(); MEDCouplingMeshType getType() const; + std::size_t getHeapMemorySize() const; void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); int getNumberOfCells() const; int getNumberOfNodes() const; diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 805b4a7c5..da93e7a6e 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -127,6 +127,18 @@ void MEDCouplingField::updateTime() const updateTimeWith(*_type); } +std::size_t MEDCouplingField::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_name.capacity(); + ret+=_desc.capacity(); + if(_mesh) + ret+=_mesh->getHeapMemorySize(); + if((const MEDCouplingFieldDiscretization *)_type) + ret+=_type->getHeapMemorySize(); + return ret; +} + TypeOfField MEDCouplingField::getTypeOfField() const { return _type->getEnum(); diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 69e6752ee..6dbe8bfdd 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -82,6 +82,7 @@ namespace ParaMEDMEM void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; protected: MEDCouplingField(TypeOfField type); MEDCouplingField(const MEDCouplingField& other); diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 80b9d6a63..461efc9aa 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -128,6 +128,11 @@ void MEDCouplingFieldDiscretization::updateTime() const { } +std::size_t MEDCouplingFieldDiscretization::getHeapMemorySize() const +{ + return 0; +} + /*! * Computes normL1 of DataArrayDouble instance arr. * @param res output parameter expected to be of size arr->getNumberOfComponents(); @@ -449,6 +454,8 @@ void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMe MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getMeasureField : mesh instance specified is NULL !"); return mesh->getMeasureField(isAbs); } @@ -488,8 +495,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArr oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! "; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -522,7 +528,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellI MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc((int)std::distance(startCellIds,endCellIds),1); std::copy(startCellIds,endCellIds,ret->getPointer()); - ret->incrRef(); return ret; + return ret.retn(); } /*! @@ -685,6 +691,8 @@ void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfFiel MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getMeasureField : mesh instance specified is NULL !"); return mesh->getMeasureFieldOnNode(isAbs); } @@ -747,8 +755,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP1::getValueOnMulti(const DataArr oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! "; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - ret->incrRef(); - return ret; + return ret.retn(); } MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) @@ -779,6 +786,14 @@ void MEDCouplingFieldDiscretizationPerCell::updateTime() const updateTimeWith(*_discr_per_cell); } +std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_discr_per_cell) + ret+=_discr_per_cell->getHeapMemorySize(); + return ret; +} + void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) { if(!_discr_per_cell) @@ -951,6 +966,14 @@ std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const return oss.str(); } +std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySize() const +{ + std::size_t ret=_loc.capacity()*sizeof(MEDCouplingGaussLocalization); + for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++) + ret+=(*it).getHeapMemorySize(); + return MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize()+ret; +} + const char *MEDCouplingFieldDiscretizationGauss::getRepr() const { return REPR; @@ -992,8 +1015,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplin throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, @@ -1183,6 +1205,8 @@ void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplin MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : mesh instance specified is NULL !"); throw INTERP_KERNEL::Exception("Not implemented yet !"); } @@ -1407,8 +1431,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellFie valsToFill[i]=_loc[*w].getNumberOfGaussPt(); else throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : orphan cell detected !"); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -1605,6 +1628,8 @@ void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCoupl MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !"); throw INTERP_KERNEL::Exception("Not implemented yet !"); } @@ -1705,6 +1730,8 @@ bool MEDCouplingFieldDiscretizationKriging::isEqualIfNotWhy(const MEDCouplingFie MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationKriging::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getMeasureField : mesh instance specified is NULL !"); throw INTERP_KERNEL::Exception("getMeasureField on FieldDiscretizationKriging : not implemented yet !"); } @@ -1745,8 +1772,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const Da MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbOfTargetPoints,nbOfCompo); INTERP_KERNEL::matrixProduct(KnewiK->getConstPointer(),1,nbOfPts+delta,matrix3->getConstPointer(),nbOfPts+delta,nbOfTargetPoints*nbOfCompo,ret->getPointer()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -1779,8 +1805,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficie double *work=std::copy(arr->begin(),arr->end(),arr2->getPointer()); std::fill(work,work+isDrift,0.); INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbOfPts+isDrift,nbOfPts+isDrift,arr2->getConstPointer(),nbOfPts+isDrift,1,KnewiK->getPointer()); - KnewiK->incrRef(); - return KnewiK; + return KnewiK.retn(); } /*! @@ -1850,7 +1875,6 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataA destWork+=spaceDimension; } // - ret->incrRef(); - return ret; + return ret.retn(); } diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 6efe4aae1..8e194911f 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -46,6 +46,7 @@ namespace ParaMEDMEM double getPrecision() const { return _precision; } void setPrecision(double val) { _precision=val; } void updateTime() const; + std::size_t getHeapMemorySize() const; static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); virtual TypeOfField getEnum() const = 0; virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; @@ -191,6 +192,7 @@ namespace ParaMEDMEM MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds); ~MEDCouplingFieldDiscretizationPerCell(); void updateTime() const; + std::size_t getHeapMemorySize() const; void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; @@ -214,6 +216,7 @@ namespace ParaMEDMEM MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; std::string getStringRepr() const; const char *getRepr() const; + std::size_t getHeapMemorySize() const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 36c10e825..f2fb7e1bd 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -33,26 +33,64 @@ using namespace ParaMEDMEM; +/*! + * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field. + * + * \param [in] type type of spatial discretization of a created field (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", \ref ParaMEDMEM::ON_NODES "ON_NODES", \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). + * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + + * \return a newly allocated field the caller should deal with. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td) { return new MEDCouplingFieldDouble(type,td); } +/*! + * Creates a new instance of MEDCouplingFieldDouble of given type. The caller is responsable for the returned field. + * + * \param [in] ft \ref MEDCouplingFieldTemplatesPage "field template" defining its spatial discretization and supporting mesh. + * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL") + + * \return a newly allocated field the caller should deal with. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td) { return new MEDCouplingFieldDouble(ft,td); } +/*! + * Sets time \a unit of \a this field. + * + * \param [in] unit \a unit (string) in which time is measured. + */ void MEDCouplingFieldDouble::setTimeUnit(const char *unit) { _time_discr->setTimeUnit(unit); } +/*! + * Returns a time unit of \a this field. + * + * \return a string describing units in which time is measured. + */ const char *MEDCouplingFieldDouble::getTimeUnit() const { return _time_discr->getTimeUnit(); } +/*! + * This method if possible the time information (time unit, time iteration, time unit and time value) with its support + * that is to say its mesh. + * + * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is + * NO_TIME. + */ +void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception) +{ + _time_discr->synchronizeTimeWith(_mesh); +} + /*! * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method). * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false. @@ -62,11 +100,12 @@ const char *MEDCouplingFieldDouble::getTimeUnit() const * It allows the user to perform methods * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field. * - * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this \b whatever \b the \b value \b of \b recDeepCpy \b parameter. + * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this **whatever the value** of \a recDeepCpy parameter. * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead. * - * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied of only attached to the returned field. + * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field. * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with. + * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const { @@ -74,12 +113,17 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const } /*! - * This method behaves exactly like MEDCouplingFieldDouble::clone method \b except \b that \b here \b the \b underlying \b mesh \b is \b systematically - * (whatever the value of the input parameter 'recDeepCpy') \b deeply \b duplicated.\n \n + * This method behaves exactly like MEDCouplingFieldDouble::clone method **except that here the underlying mesh is systematically ** + * (whatever the value of the input parameter \a recDeepCpy) **deeply duplicated**. + * * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy". * * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ... * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead. + + * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied or only attached to the returned field. + * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with. + * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const { @@ -94,16 +138,31 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) c } /*! - * This method performs a deepCpy of \a this \b mesh \b included ! + * This method performs a deepCpy of \a this (**mesh included**)! * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ... - * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead. + * To avoid deep copying the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead. * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true. + * + * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with. + * \sa ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const { return cloneWithMesh(true); } +/*! + * TODOC + * + * \param [in] td type of time discretization of a created field (\ref ParaMEDMEM::NO_TIME "NO_TIME", \ref ParaMEDMEM::ONE_TIME "ONE_TIME", \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * \param [in] deepCopy specifies if underlying arrays in \a this should be copied or only attached to the returned field. + * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with. + * + * \ref cpp_mcfielddouble_buildnewtimereprfromthis "Here a C++ example." + + * \ref py_mcfielddouble_buildnewtimereprfromthis "Here a Python example." + * \sa ParaMEDMEM::MEDCouplingFieldDouble::clone(bool recDeepCpy) const + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const { MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); @@ -191,6 +250,12 @@ std::string MEDCouplingFieldDouble::advancedRepr() const return ret.str(); } +void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception) +{ + std::vector fs(1,this); + MEDCouplingFieldDouble::WriteVTK(fileName,fs); +} + bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!other) @@ -1074,12 +1139,35 @@ void MEDCouplingFieldDouble::updateTime() const updateTimeWith(*_time_discr); } +std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_time_discr) + ret+=_time_discr->getHeapMemorySize(); + return MEDCouplingField::getHeapMemorySize()+ret; +} + void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception) { MEDCouplingField::setNature(nat); _type->checkCompatibilityWithNature(nat); } +/*! + * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh. + * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME) + */ +void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !"); + int it=-1,ordr=-1; + double val=_mesh->getTime(it,ordr); + std::string timeUnit(_mesh->getTimeUnit()); + setTime(val,it,ordr); + setTimeUnit(timeUnit.c_str()); +} + double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const { return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId); @@ -1362,7 +1450,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori } } ret->setArrays(newArr); - ret->incrRef(); return ret; + return ret.retn(); } /*! diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 45a553b6b..3b275f9de 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -33,14 +33,16 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldDouble : public MEDCouplingField { public: - static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME); + static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME); void setTimeUnit(const char *unit); const char *getTimeUnit() const; + void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; + void writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; bool areCompatibleForMerge(const MEDCouplingField *other) const; @@ -71,6 +73,7 @@ namespace ParaMEDMEM void setTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setTimeValue(val); } void setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setEndTimeValue(val); } void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } + void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } @@ -125,6 +128,7 @@ namespace ParaMEDMEM int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); int getNumberOfValues() const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; // void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx index 1b5df9b07..abab57f5a 100644 --- a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx +++ b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx @@ -87,6 +87,15 @@ std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const return oss.str(); } +std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_ref_coord.capacity()*sizeof(double); + ret+=_gauss_coord.capacity()*sizeof(double); + ret+=_weight.capacity()*sizeof(double); + return ret; +} + bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const { if(_type!=other._type) diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.hxx b/src/MEDCoupling/MEDCouplingGaussLocalization.hxx index 49f843e7e..31adcb852 100644 --- a/src/MEDCoupling/MEDCouplingGaussLocalization.hxx +++ b/src/MEDCoupling/MEDCouplingGaussLocalization.hxx @@ -41,6 +41,7 @@ namespace ParaMEDMEM int getDimension() const; int getNumberOfPtsInRefCell() const; std::string getStringRepr() const; + std::size_t getHeapMemorySize() const; void checkCoherency() const throw(INTERP_KERNEL::Exception); bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; void pushTinySerializationIntInfo(std::vector& tinyInfo) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 9081b8ecb..4436fa7d1 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -36,7 +36,7 @@ typedef double (*MYFUNCPTR)(double); using namespace ParaMEDMEM; template -void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const +void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const { const double *coordsPtr=getConstPointer(); BBTree myTree(bbox,0,0,nbNodes,prec/10); @@ -59,9 +59,9 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l } if(!commonNodes.empty()) { - cI.push_back(cI.back()+(int)commonNodes.size()+1); - c.push_back(i); - c.insert(c.end(),commonNodes.begin(),commonNodes.end()); + cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1); + c->pushBackSilent(i); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); } } } @@ -70,7 +70,7 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l template void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double *pos, int nbOfTuples, double eps, - std::vector& c, std::vector& cI) + DataArrayInt *c, DataArrayInt *cI) { for(int i=0;i& myTr std::vector commonNodes; for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) commonNodes.push_back(*it); - cI.push_back(cI.back()+(int)commonNodes.size()); - c.insert(c.end(),commonNodes.begin(),commonNodes.end()); + cI->pushBackSilent(cI->back()+(int)commonNodes.size()); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); } } +std::size_t DataArray::getHeapMemorySize() const +{ + std::size_t sz1=_name.capacity(); + std::size_t sz2=_info_on_compo.capacity(); + std::size_t sz3=0; + for(std::vector::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + sz3+=(*it).capacity(); + return sz1+sz2+sz3; +} + void DataArray::setName(const char *name) { _name=name; @@ -130,12 +140,6 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, cons bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const { std::ostringstream oss; - if(_nb_of_tuples!=other._nb_of_tuples) - { - oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples; - reason=oss.str(); - return false; - } if(_name!=other._name) { oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !"; @@ -383,6 +387,8 @@ int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char std::ostringstream oss; oss << msg << " : end before begin !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(end==begin) + return 0; if(step<=0) { std::ostringstream oss; oss << msg << " : invalid step should be > 0 !"; @@ -460,6 +466,13 @@ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } +std::size_t DataArrayDouble::getHeapMemorySize() const +{ + std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated(); + sz*=sizeof(double); + return DataArray::getHeapMemorySize()+sz; +} + /*! * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' * and if 'this' is not allocated it will change the number of components of 'this'. @@ -541,6 +554,49 @@ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL: copyStringInfoFrom(other); } +void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + { + _mem.reserve(nbOfElems); + } + else if(nbCompo==0) + { + _mem.reserve(nbOfElems); + _info_on_compo.resize(1); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !"); +} + +void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.pushBack(val); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.pushBack(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !"); +} + +double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception) +{ + if(getNumberOfComponents()==1) + return _mem.popBack(); + else + throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !"); +} + +void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception) +{ + _mem.pack(); +} + void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) { if(isAllocated()) @@ -556,9 +612,8 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::E { if(nbOfTuple<0 || nbOfCompo<0) throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !"); - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); - _mem.alloc(nbOfCompo*_nb_of_tuples); + _mem.alloc(nbOfCompo*nbOfTuple); declareAsNew(); } @@ -627,16 +682,12 @@ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) */ void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) { - if(!isMonotonic(increasing, eps)) + if(!isMonotonic(increasing,eps)) { if (increasing) - { - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); - } + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); else - { - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); - } + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); } } @@ -655,7 +706,7 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTER return true; double ref=ptr[0]; double absEps=fabs(eps); - if (increasing) + if(increasing) { for(int i=1;igetNumberOfTuples) !"); ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -961,8 +1010,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c for(int i=0;icopyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -1019,8 +1067,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vectorgetPointer(); for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -1097,7 +1144,6 @@ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception int nbOfElems=getNbOfElems(); if(nbOfElems%newNbOfCompo!=0) throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !"); - _nb_of_tuples=nbOfElems/newNbOfCompo; _info_on_compo.clear(); _info_on_compo.resize(newNbOfCompo); declareAsNew(); @@ -1135,8 +1181,7 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& for(int i=0;iincrRef(); - return ret; + return ret.retn(); } /*! @@ -1193,12 +1238,10 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3."); int nbOfTuples=getNumberOfTuples(); - comm=DataArrayInt::New(); - commIndex=DataArrayInt::New(); // MEDCouplingAutoRefCountObjectPtr bbox=computeBBoxPerTuple(prec); // - std::vector c,cI(1); + MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); switch(nbOfCompo) { case 3: @@ -1213,10 +1256,8 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI default: throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !"); } - commIndex->alloc((int)cI.size(),1); - std::copy(cI.begin(),cI.end(),commIndex->getPointer()); - comm->alloc(cI.back(),1); - std::copy(c.begin(),c.end(),comm->getPointer()); + comm=c.retn(); + commIndex=cI.retn(); } /*! @@ -1244,8 +1285,7 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th *retPtr=val; } ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -1263,7 +1303,7 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple findCommonTuples(prec,limitTupleId,c0,cI0); MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples); + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); } @@ -1639,7 +1679,6 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); declareAsNew(); @@ -1647,7 +1686,6 @@ void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); declareAsNew(); @@ -1723,8 +1761,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon; } } - bbox->incrRef(); - return bbox; + return bbox.retn(); } /*! @@ -1745,7 +1782,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw * * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues */ -void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception) +void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !"); @@ -1756,32 +1793,31 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do if(nbOfCompo!=otherNbOfCompo) throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !"); int nbOfTuplesOther=other->getNumberOfTuples(); - std::vector ret; - c.clear(); - cI.resize(1); cI[0]=0; + MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); switch(nbOfCompo) { case 3: { BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } case 2: { BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } case 1: { BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3."); } + c=cArr.retn(); cI=cIArr.retn(); } /*! @@ -1920,6 +1956,45 @@ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Excepti std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus()); } +/*! + * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and + * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown. + * + * + * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to + * \a tupleEnd. If not an exception will be thrown. + * + * \param [in] tupleBg start pointer (included) of input external tuple + * \param [in] tupleEnd end pointer (not included) of input external tuple + * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple + * \return the min distance. + * \sa MEDCouplingUMesh::distanceToPoint + */ +double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + if(nbComps!=(int)std::distance(tupleBg,tupleEnd)) + { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(nbTuple==0) + throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !"); + double ret0=std::numeric_limits::max(); + tupleId=-1; + const double *work=getConstPointer(); + for(int i=0;i=ret0) + continue; + else + { ret0=val; tupleId=i; } + } + return sqrt(ret0); +} + double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2230,8 +2305,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const thro outData[j*nbOfTuples+i]=dist; } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -2281,8 +2355,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da outData[i*nbOfTuples+j]=dist; } } - ret->incrRef(); - return ret; + return ret.retn(); } void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) @@ -2864,8 +2937,7 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - ret->incrRef(); - return ret; + return ret.retn(); } void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) @@ -2926,8 +2998,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -2939,8 +3010,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -2958,8 +3028,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -3077,8 +3146,7 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - ret->incrRef(); - return ret; + return ret.retn(); } void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) @@ -3139,8 +3207,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -3152,8 +3219,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -3171,8 +3237,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -3385,6 +3450,13 @@ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } +std::size_t DataArrayInt::getHeapMemorySize() const +{ + std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated(); + sz*=sizeof(int); + return DataArray::getHeapMemorySize()+sz; +} + /*! * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' * and if 'this' is not allocated it will change the number of components of 'this'. @@ -3484,6 +3556,49 @@ void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Excep copyStringInfoFrom(other); } +void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + { + _mem.reserve(nbOfElems); + } + else if(nbCompo==0) + { + _mem.reserve(nbOfElems); + _info_on_compo.resize(1); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !"); +} + +void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.pushBack(val); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.pushBack(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !"); +} + +int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception) +{ + if(getNumberOfComponents()==1) + return _mem.popBack(); + else + throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !"); +} + +void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception) +{ + _mem.pack(); +} + void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) { if(isAllocated()) @@ -3498,10 +3613,9 @@ void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { if(nbOfTuple<0 || nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !"); - _nb_of_tuples=nbOfTuple; + throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !"); _info_on_compo.resize(nbOfCompo); - _mem.alloc(nbOfCompo*_nb_of_tuples); + _mem.alloc(nbOfCompo*nbOfTuple); declareAsNew(); } @@ -3680,12 +3794,9 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, } ret3->alloc((int)castsDetected.size(),1); std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer()); - ret1->incrRef(); - castArr=ret1; - ret2->incrRef(); - rankInsideCast=ret2; - ret3->incrRef(); - castsPresent=ret3; + castArr=ret1.retn(); + rankInsideCast=ret2.retn(); + castsPresent=ret3.retn(); } /*! @@ -3718,12 +3829,12 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering. + * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [3,1,2,4,9,6,8] */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { @@ -3738,6 +3849,23 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const return ret; } +/*! + * This method is similar to DataArrayInt::invertArrayO2N2N2O except that + * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8] + */ +DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(newNbOfElem,1); + int nbOfOldNodes=getNumberOfTuples(); + const int *old2New=getConstPointer(); + int *pt=ret->getPointer(); + for(int i=nbOfOldNodes-1;i>=0;i--) + if(old2New[i]!=-1) + pt[old2New[i]]=i; + return ret; +} + /*! * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering. */ @@ -3798,6 +3926,106 @@ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) _mem.reverse(); } +/*! + * This method check that array consistently INCREASING or DECREASING in value. + */ +void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) +{ + if(!isMonotonic(increasing)) + { + if (increasing) + throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !"); + else + throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !"); + } +} + +/*! + * This method check that array consistently INCREASING or DECREASING in value. + */ +bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !"); + int nbOfElements=getNumberOfTuples(); + const int *ptr=getConstPointer(); + if(nbOfElements==0) + return true; + int ref=ptr[0]; + if(increasing) + { + for(int i=1;i=ref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;iref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;iincrRef(); - return ret; + return ret.retn(); } void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); declareAsNew(); @@ -3845,7 +4071,6 @@ void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); declareAsNew(); @@ -3957,7 +4182,7 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup } /*! - * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. + * This method is a generalization of DataArrayInt::substr method because a not contigous range can be specified here. * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new. */ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const @@ -3994,8 +4219,7 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int else throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -4017,8 +4241,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t for(int i=0;icopyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -4075,15 +4298,14 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vectorgetPointer(); for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - ret->incrRef(); - return ret; + return ret.retn(); } /*! * This method works only for arrays having single component. * If this contains the array a1 containing [9,10,0,6,4,11,3,7] this method returns an array a2 [5,6,0,3,2,7,1,4]. * By doing a1.renumber(a2) the user will obtain array a3 equal to a1 sorted. - * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldDouble::renumberCells when check is set to true. + * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldInt::renumberCells when check is set to true. * This method throws an exception if more 2 or more elements in 'this' are same. */ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception) @@ -4142,36 +4364,32 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data int *retPtr=ret->getPointer(); for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++) retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr); - ret->incrRef(); - retI->incrRef(); - arr=ret; - arrI=retI; + arr=ret.retn(); + arrI=retI.retn(); } /*! - * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example) + * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayInt::findCommonTuples for example) * The retrieved array minimizes the permutation. * Let's take an example : * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7. * * @param nbOfOldTuples is the number of tuples in initial array. * @param arr is the list of tuples ids grouped by 'arrI' array - * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. + * @param arrIBg is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. + * @param arrIEnd is the entry point of 'arr' array (end not included) * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application */ -DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) +DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) { - if(!arr || !arrI) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !"); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfOldTuples,1); int *pt=ret->getPointer(); std::fill(pt,pt+nbOfOldTuples,-1); - int nbOfGrps=arrI->getNumberOfTuples()-1; - const int *cIPtr=arrI->getConstPointer(); - const int *cPtr=arr->getConstPointer(); + int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; + const int *cIPtr=arrIBg; for(int i=0;i=0 && arr[j]incrRef(); - return ret; + return ret.retn(); } /*! @@ -4333,7 +4558,6 @@ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) int nbOfElems=getNbOfElems(); if(nbOfElems%newNbOfCompo!=0) throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !"); - _nb_of_tuples=nbOfElems/newNbOfCompo; _info_on_compo.clear(); _info_on_compo.resize(newNbOfCompo); declareAsNew(); @@ -4384,8 +4608,7 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { checkAllocated(); - _mem.reAlloc((int)_info_on_compo.size()*nbOfTuples); - _nb_of_tuples=nbOfTuples; + _mem.reAlloc(getNumberOfComponents()*nbOfTuples); declareAsNew(); } @@ -4405,8 +4628,7 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compo for(int i=0;iincrRef(); - return ret; + return ret.retn(); } /*! @@ -4816,15 +5038,12 @@ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exce if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception) @@ -4832,15 +5051,12 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } /*! @@ -5031,6 +5247,32 @@ bool DataArrayInt::presenceOfValue(const std::vector& vals) const throw(INT return locateValue(vals)!=-1; } + +void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const int *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + std::fill(res,res+nbComps,0); + for(int i=0;i()); +} + +int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const int *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + if(compId>=nbComps) + throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !"); + int ret=0; + for(int i=0;iincrRef(); - return ret; + return ret.retn(); } DataArrayInt *DataArrayInt::BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception) @@ -5472,6 +5713,9 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_ return ret; } +/*! + * \sa DataArrayInt::buildSubstractionOptimized + */ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { if(!other) @@ -5496,6 +5740,33 @@ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const t return ret; } +/*! + * \a this is expected to have one component and to be sorted ascendingly (as for \a other). + * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead. + * + * \param [in] other an array with one component and expected to be sorted ascendingly. + * \ret list of ids in \a this but not in \a other. + * \sa DataArrayInt::buildSubstraction + */ +DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) +{ + static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !"; + if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !"); + checkAllocated(); other->checkAllocated(); + if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + for(;work1!=pt1End;work1++) + { + if(work2!=pt2End && *work1==*work2) + work2++; + else + ret->pushBackSilent(*work1); + } + return ret.retn(); +} + DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { std::vectorarrs(2); @@ -5530,8 +5801,7 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(std::distance(data,last),1); std::copy(data,last,ret->getPointer()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5661,8 +5931,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets for(int j=0;jincrRef(); - return ret; + return ret.retn(); } /*! @@ -5711,8 +5980,7 @@ DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5761,8 +6029,7 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5790,8 +6057,7 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN *retPtr=val; } ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5909,8 +6175,7 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - ret->incrRef(); - return ret; + return ret.retn(); } void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) @@ -5971,8 +6236,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -5984,8 +6248,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6003,8 +6266,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6117,8 +6379,7 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - ret->incrRef(); - return ret; + return ret.retn(); } void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) @@ -6179,8 +6440,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -6192,8 +6452,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6211,8 +6470,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6279,8 +6537,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -6292,8 +6549,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6311,8 +6567,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6399,8 +6654,7 @@ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KER for(int i=begin;i>end;i+=step,ptr++) *ptr=i; } - ret->incrRef(); - return ret; + return ret.retn(); } /*! diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 6b8b5853f..eaa272724 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -55,11 +55,13 @@ namespace ParaMEDMEM class MemArray { public: - MemArray():_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) { } + MemArray():_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(CPP_DEALLOC) { } MemArray(const MemArray& other); bool isNull() const { return _pointer.isNull(); } const T *getConstPointerLoc(int offset) const { return _pointer.getConstPointerLoc(offset); } const T *getConstPointer() const { return _pointer.getConstPointer(); } + int getNbOfElem() const { return _nb_of_elem; } + int getNbOfElemAllocated() const { return _nb_of_elem_alloc; } T *getPointer() { return _pointer.getPointer(); } MemArray &operator=(const MemArray& other); T operator[](int id) const { return _pointer.getConstPointer()[id]; } @@ -73,16 +75,23 @@ namespace ParaMEDMEM void sort(bool asc); void reverse(); void alloc(int nbOfElements) throw(INTERP_KERNEL::Exception); + void reserve(int newNbOfElements) throw(INTERP_KERNEL::Exception); void reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception); void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem); void useExternalArrayWithRWAccess(const T *array, int nbOfElem); void writeOnPlace(int id, T element0, const T *others, int sizeOfOthers); + template + void insertAtTheEnd(InputIterator first, InputIterator last); + void pushBack(T elem) throw(INTERP_KERNEL::Exception); + T popBack() throw(INTERP_KERNEL::Exception); + void pack() const; ~MemArray() { destroy(); } private: void destroy(); static void destroyPointer(T *pt, DeallocType type); private: int _nb_of_elem; + int _nb_of_elem_alloc; bool _ownership; MEDCouplingPointer _pointer; DeallocType _dealloc; @@ -91,6 +100,7 @@ namespace ParaMEDMEM class DataArray : public RefCountObject, public TimeLabel { public: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT void setName(const char *name); MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); @@ -110,8 +120,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); } - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; } - MEDCOUPLING_EXPORT int getNbOfElems() const { return ((int)_info_on_compo.size())*_nb_of_tuples; } + MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const = 0; + MEDCOUPLING_EXPORT virtual int getNbOfElems() const = 0; MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception); @@ -124,13 +134,12 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT virtual void reprCppStream(const char *varName, std::ostream& stream) const = 0; protected: - DataArray():_nb_of_tuples(-1) { } + DataArray() { } protected: static void CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception); static void CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception); static void CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception); protected: - int _nb_of_tuples; std::string _name; std::vector _info_on_compo; }; @@ -148,12 +157,20 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayDouble *New(); MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT int getNbOfElems() const { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double doubleValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reserve(int nbOfElems) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackSilent(double val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double popBackSilent() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); @@ -222,11 +239,13 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT const double *end() const { return getConstPointer()+getNbOfElems(); } MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo); + template + void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT void checkNoNullValues() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMaxValueInArray() const throw(INTERP_KERNEL::Exception); @@ -239,6 +258,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT double normMax() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void accumulate(double *res) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double accumulate(int compId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception); @@ -292,10 +312,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); public: template - void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const; + void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const; template static void FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double *pos, int nbOfTuples, double eps, - std::vector& c, std::vector& cI); + DataArrayInt *c, DataArrayInt *cI); private: DataArrayDouble() { } private: @@ -341,6 +361,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayInt *New(); MEDCOUPLING_EXPORT bool isAllocated() const; MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT int getNbOfElems() const { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int intValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getHashCode() const throw(INTERP_KERNEL::Exception); @@ -348,6 +371,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reserve(int nbOfElems) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackSilent(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int popBackSilent() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; @@ -357,6 +385,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void sort(bool asc=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithValue(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void iota(int init=0) throw(INTERP_KERNEL::Exception); @@ -374,6 +406,7 @@ namespace ParaMEDMEM DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; + MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception); //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; @@ -390,7 +423,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isIdentity() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isUniform(int val) const throw(INTERP_KERNEL::Exception); @@ -434,6 +467,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void accumulate(int *res) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int accumulate(int compId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMaxValueInArray() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); @@ -456,6 +491,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception); @@ -469,7 +505,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::set getDifferentValues() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); + void MEDCOUPLING_EXPORT useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); + template + void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); @@ -527,6 +565,36 @@ namespace ParaMEDMEM int *_pt; int _nb_of_compo; }; + + template + void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception) + { + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(first,last); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(first,last); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::insertAtTheEnd : not available for DataArrayDouble with number of components different than 1 !"); + } + + template + void DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception) + { + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(first,last); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(first,last); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::insertAtTheEnd : not available for DataArrayInt with number of components different than 1 !"); + } } #endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index e569249d8..35404431b 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -17,6 +17,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // Author : Anthony Geay (CEA/DEN) + #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ @@ -45,11 +46,12 @@ namespace ParaMEDMEM } template - MemArray::MemArray(const MemArray& other):_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) + MemArray::MemArray(const MemArray& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(CPP_DEALLOC) { if(!other._pointer.isNull()) { - T *pointer=new T[other._nb_of_elem]; + _nb_of_elem_alloc=other._nb_of_elem; + T *pointer=new T[_nb_of_elem_alloc]; std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer); useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem); } @@ -59,6 +61,7 @@ namespace ParaMEDMEM void MemArray::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem) { _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; destroy(); if(ownership) _pointer.setInternal(const_cast(array)); @@ -72,6 +75,7 @@ namespace ParaMEDMEM void MemArray::useExternalArrayWithRWAccess(const T *array, int nbOfElem) { _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; destroy(); _pointer.setInternal(const_cast(array)); _ownership=false; @@ -81,11 +85,55 @@ namespace ParaMEDMEM template void MemArray::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers) { - if(id+sizeOfOthers>=_nb_of_elem) - reAlloc(2*_nb_of_elem+sizeOfOthers+1); + if(id+sizeOfOthers>=_nb_of_elem_alloc) + reserve(2*_nb_of_elem+sizeOfOthers+1); T *pointer=_pointer.getPointer(); pointer[id]=element0; std::copy(others,others+sizeOfOthers,pointer+id+1); + _nb_of_elem=std::max(_nb_of_elem,id+sizeOfOthers+1); + } + + template + template + void MemArray::insertAtTheEnd(InputIterator first, InputIterator last) + { + T *pointer=_pointer.getPointer(); + while(first!=last) + { + if(_nb_of_elem>=_nb_of_elem_alloc || _nb_of_elem==0) + { + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + pointer=_pointer.getPointer(); + } + pointer[_nb_of_elem++]=*first++; + } + } + + template + void MemArray::pushBack(T elem) throw(INTERP_KERNEL::Exception) + { + if(_nb_of_elem>=_nb_of_elem_alloc) + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + T *pt=getPointer(); + pt[_nb_of_elem++]=elem; + } + + template + T MemArray::popBack() throw(INTERP_KERNEL::Exception) + { + if(_nb_of_elem>0) + { + const T *pt=getConstPointer(); + return pt[--_nb_of_elem]; + } + throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !"); + } + + template + void MemArray::pack() const + { + if(_nb_of_elem>=0) + (const_cast * >(this))->reserve(_nb_of_elem); } template @@ -121,7 +169,7 @@ namespace ParaMEDMEM } /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components */ template void MemArray::repr(int sl, std::ostream& stream) const @@ -130,8 +178,8 @@ namespace ParaMEDMEM if(!_pointer.isNull()) { if(sl!=0) - stream << _nb_of_elem/sl; - else + stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc; + else stream << "Empty Data"; } else @@ -160,7 +208,7 @@ namespace ParaMEDMEM } /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components */ template void MemArray::reprZip(int sl, std::ostream& stream) const @@ -260,22 +308,60 @@ namespace ParaMEDMEM if(nbOfElements<0) throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !"); _nb_of_elem=nbOfElements; - _pointer.setInternal(new T[_nb_of_elem]); + _nb_of_elem_alloc=nbOfElements; + _pointer.setInternal(new T[_nb_of_elem_alloc]); _ownership=true; _dealloc=CPP_DEALLOC; } - + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray::reAlloc method. + * So after the call of this method \a _nb_of_elem will be equal tostd::min(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to + * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation. + * So after the call of this method the accessible content is perfectly set. + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ + template + void MemArray::reserve(int newNbOfElements) throw(INTERP_KERNEL::Exception) + { + if(newNbOfElements<0) + throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !"); + if(_nb_of_elem_alloc==newNbOfElements) + return ; + T *pointer=new T[newNbOfElements]; + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); + if(_ownership) + destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external + _pointer.setInternal(pointer); + _nb_of_elem=std::min(_nb_of_elem,newNbOfElements); + _nb_of_elem_alloc=newNbOfElements; + _ownership=true; + _dealloc=CPP_DEALLOC; + } + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min(_nb_of_elem,newNbOfElements) come from the . + * The remaing part of the new allocated chunk are available but not set previouly ! + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ template void MemArray::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception) { if(newNbOfElements<0) throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !"); + if(_nb_of_elem==newNbOfElements) + return ; T *pointer=new T[newNbOfElements]; std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); if(_ownership) destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external _pointer.setInternal(pointer); _nb_of_elem=newNbOfElements; + _nb_of_elem_alloc=newNbOfElements; _ownership=true; _dealloc=CPP_DEALLOC; } diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index e0a9c7883..38e09721d 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -43,6 +43,11 @@ MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name { } +std::size_t MEDCouplingMesh::getHeapMemorySize() const +{ + return _name.capacity()+_description.capacity()+_time_unit.capacity(); +} + /*! * This method is only for ParaMEDMEM in ParaFIELD constructor. */ @@ -232,11 +237,11 @@ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -292,11 +297,11 @@ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTER */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -312,11 +317,11 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic2(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -332,11 +337,11 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nb */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic3(nbOfComp,varsOrder,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 2febf8c6b..9f86a7445 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -37,7 +37,8 @@ namespace ParaMEDMEM UNSTRUCTURED = 5, UNSTRUCTURED_DESC = 6, CARTESIAN = 7, - EXTRUDED = 8 + EXTRUDED = 8, + CURVE_LINEAR = 9 } MEDCouplingMeshType; class DataArrayInt; @@ -48,6 +49,7 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingMesh : public RefCountObject, public TimeLabel { public: + std::size_t getHeapMemorySize() const; void setName(const char *name) { _name=name; } const char *getName() const { return _name.c_str(); } void setDescription(const char *descr) { _description=descr; } diff --git a/src/MEDCoupling/MEDCouplingMultiFields.cxx b/src/MEDCoupling/MEDCouplingMultiFields.cxx index 94856e43d..d26186768 100644 --- a/src/MEDCoupling/MEDCouplingMultiFields.cxx +++ b/src/MEDCoupling/MEDCouplingMultiFields.cxx @@ -190,6 +190,22 @@ void MEDCouplingMultiFields::updateTime() const updateTimeWith(*(*it)); } +std::size_t MEDCouplingMultiFields::getHeapMemorySize() const +{ + std::vector tmp; + std::vector< std::vector > tmp2; + std::vector ms=getDifferentMeshes(tmp); + std::vector arrs=getDifferentArrays(tmp2); + std::size_t ret=0; + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + std::vector MEDCouplingMultiFields::getMeshes() const throw(INTERP_KERNEL::Exception) { std::vector ms; diff --git a/src/MEDCoupling/MEDCouplingMultiFields.hxx b/src/MEDCoupling/MEDCouplingMultiFields.hxx index 16e25852c..a328a891b 100644 --- a/src/MEDCoupling/MEDCouplingMultiFields.hxx +++ b/src/MEDCoupling/MEDCouplingMultiFields.hxx @@ -59,6 +59,7 @@ namespace ParaMEDMEM virtual std::vector getArrays() const throw(INTERP_KERNEL::Exception); virtual std::vector getDifferentArrays(std::vector< std::vector >& refs) const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; void getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const; void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& ft, const std::vector& ms, diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index f2acae753..6a3f9df19 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -75,6 +75,14 @@ void MEDCouplingPointSet::updateTime() const } } +std::size_t MEDCouplingPointSet::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_coords) + ret+=_coords->getHeapMemorySize(); + return MEDCouplingMesh::getHeapMemorySize()+ret; +} + void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) { if( coords != _coords ) @@ -225,10 +233,11 @@ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArra _coords->findCommonTuples(prec,limitNodeId,comm,commIndex); } -std::vector MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception) { - std::vector c,cI; + DataArrayInt *c=0,*cI=0; getNodeIdsNearPoints(pos,1,eps,c,cI); + MEDCouplingAutoRefCountObjectPtr cITmp(cI); return c; } @@ -237,7 +246,7 @@ std::vector MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, dou * Position 'pos' is expected to be of size getSpaceDimension()*nbOfNodes. If not the behabiour is not warranted. * This method throws an exception if no coordiantes are set. */ -void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception) +void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception) { if(!_coords) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !"); @@ -257,7 +266,7 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const { if(!_coords) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); - return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm,commIndex,newNbOfNodes); + return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); } /* @@ -411,14 +420,12 @@ void MEDCouplingPointSet::scale(const double *point, double factor) double *coords=_coords->getPointer(); int nbNodes=getNumberOfNodes(); int dim=getSpaceDimension(); - double *tmp=new double[dim]; for(int i=0;i()); std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); } - delete [] tmp; _coords->declareAsNew(); updateTime(); } @@ -703,6 +710,12 @@ void MEDCouplingPointSet::unserialization(const std::vector& tinyInfoD, } } +void MEDCouplingPointSet::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !"); +} + /*! * Intersect Bounding Box given 2 Bounding Boxes. */ diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 4e00e4770..41c5eb21a 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -52,6 +52,7 @@ namespace ParaMEDMEM ~MEDCouplingPointSet(); public: void updateTime() const; + std::size_t getHeapMemorySize() const; int getNumberOfNodes() const; int getSpaceDimension() const; void setCoords(const DataArrayDouble *coords); @@ -70,8 +71,8 @@ namespace ParaMEDMEM virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; - std::vector getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); - void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); + void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception); void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, int& newNbOfNodes) const; @@ -110,10 +111,11 @@ namespace ParaMEDMEM void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); - virtual void getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const = 0; - virtual void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) = 0; + virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; + virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; virtual DataArrayInt *zipCoordsTraducer() = 0; protected: + void checkCoherency() const throw(INTERP_KERNEL::Exception); virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0; static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); diff --git a/src/MEDCoupling/MEDCouplingRefCountObject.hxx b/src/MEDCoupling/MEDCouplingRefCountObject.hxx index c6eb6825a..943c40a06 100644 --- a/src/MEDCoupling/MEDCouplingRefCountObject.hxx +++ b/src/MEDCoupling/MEDCouplingRefCountObject.hxx @@ -23,6 +23,8 @@ #include "MEDCoupling.hxx" +#include + namespace ParaMEDMEM { typedef enum @@ -62,6 +64,7 @@ namespace ParaMEDMEM public: bool decrRef() const; void incrRef() const; + virtual std::size_t getHeapMemorySize() const = 0; protected: virtual ~RefCountObject(); private: diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx index 8a489b139..0e120ce10 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ b/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -666,8 +666,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case Integral: { - MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); - MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); + MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); + MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) @@ -698,8 +698,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case RevIntegral: { - MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); - MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); + MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); + MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx new file mode 100644 index 000000000..4d02d732b --- /dev/null +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -0,0 +1,379 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "MEDCouplingStructuredMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingUMesh.hxx" + +#include + +using namespace ParaMEDMEM; + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() +{ +} + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) +{ +} + +MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() +{ +} + +std::size_t MEDCouplingStructuredMesh::getHeapMemorySize() const +{ + return MEDCouplingMesh::getHeapMemorySize(); +} + +void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + MEDCouplingMesh::copyTinyStringsFrom(other); +} + +bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const +{ + switch(getMeshDimension()) + { + case 3: + return INTERP_KERNEL::NORM_HEXA8; + case 2: + return INTERP_KERNEL::NORM_QUAD4; + case 1: + return INTERP_KERNEL::NORM_SEG2; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCurveLinearMesh::getTypeOfCell !"); + } +} + +std::set MEDCouplingStructuredMesh::getAllGeoTypes() const +{ + INTERP_KERNEL::NormalizedCellType ret; + switch(getMeshDimension()) + { + case 3: + ret=INTERP_KERNEL::NORM_HEXA8; + break; + case 2: + ret=INTERP_KERNEL::NORM_QUAD4; + break; + case 1: + ret=INTERP_KERNEL::NORM_SEG2; + break; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::getAllGeoTypes !"); + } + std::set ret2; + ret2.insert(ret); + return ret2; +} + +int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + int ret=getNumberOfCells(); + int dim=getMeshDimension(); + switch(type) + { + case INTERP_KERNEL::NORM_HEXA8: + if(dim==3) + return ret; + case INTERP_KERNEL::NORM_QUAD4: + if(dim==2) + return ret; + case INTERP_KERNEL::NORM_SEG2: + if(dim==1) + return ret; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::getTypeOfCell !"); + } + return 0; +} + +void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const +{ + int meshDim=getMeshDimension(); + int tmpCell[3],tmpNode[3]; + getSplitCellValues(tmpCell); + getSplitNodeValues(tmpNode); + int tmp2[3]; + GetPosFromId(cellId,meshDim,tmpCell,tmp2); + switch(meshDim) + { + case 1: + conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); + break; + case 2: + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); + conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); + break; + case 3: + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); + }; +} + +/*! + * See MEDCouplingUMesh::getDistributionOfTypes for more information + */ +std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) +{ + //only one type of cell + std::vector ret(3); + ret[0]=getTypeOfCell(0); + ret[1]=getNumberOfCells(); + ret[2]=0; //ret[3*k+2]==0 because it has no sense here + return ret; +} + +/*! + * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information + */ +DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + if(code.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code is empty, should not !"); + std::size_t sz=code.size(); + if(sz!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); + + int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); + if(code[2]==-1) + { + if(code[1]==nbCells) + return 0; + else + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); + } + else + { + if(code[2]<-1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); + if(code[2]>=(int)idsPerType.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); + return idsPerType[code[2]]->deepCpy(); + } +} + +/*! + * See MEDCouplingUMesh::splitProfilePerType for more information + */ +void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + int nbCells=getNumberOfCells(); + code.resize(3); + code[0]=(int)getTypeOfCell(0); + code[1]=nbCells; + code[2]=0; + idsInPflPerType.push_back(profile->deepCpy()); + idsPerType.push_back(profile->deepCpy()); +} + +MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + int meshDim=getMeshDimension(); + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),meshDim); + DataArrayDouble *coords=getCoordinatesAndOwner(); + ret->setCoords(coords); + coords->decrRef(); + switch(meshDim) + { + case 1: + fill1DUnstructuredMesh(ret); + break; + case 2: + fill2DUnstructuredMesh(ret); + break; + case 3: + fill3DUnstructuredMesh(ret); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); + }; + return ret; +} + +MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const int *end) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPart(start,end); + um->decrRef(); + return ret; +} + +MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); + um->decrRef(); + return ret; +} + +DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::simplexize : not available for Cartesian mesh !"); +} + +MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("Expected a MEDCouplingStructuredMesh with meshDim == 2 !"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + array->alloc(nbOfCells,3); + double *vals=array->getPointer(); + for(int i=0;isetArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +void MEDCouplingStructuredMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int nbOfCells=-1; + getNodeGridStructure(&nbOfCells); + nbOfCells--; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(nbOfCells+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(3*nbOfCells,1); + ci[0]=0; + int *cp=conn->getPointer(); + for(int i=0;isetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingStructuredMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int ns[2]; + getNodeGridStructure(ns); + int n1=ns[0]-1; + int n2=ns[1]-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(5*n1*n2,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int j=0;jsetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingStructuredMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int ns[3]; + getNodeGridStructure(ns); + int n1=ns[0]-1; + int n2=ns[1]-1; + int n3=ns[2]-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2*n3+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(9*n1*n2*n3,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int k=0;ksetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +int MEDCouplingStructuredMesh::getCellIdFromPos(int i, int j, int k) const +{ + int tmp[3]={i,j,k}; + int tmp2[3]; + int meshDim=getMeshDimension(); + getSplitCellValues(tmp2); + std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); + return std::accumulate(tmp,tmp+meshDim,0); +} + +int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const +{ + int tmp[3]={i,j,k}; + int tmp2[3]; + int meshDim=getMeshDimension(); + getSplitNodeValues(tmp2); + std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); + return std::accumulate(tmp,tmp+meshDim,0); +} + +void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int *split, int *res) +{ + int work=nodeId; + for(int i=meshDim-1;i>=0;i--) + { + int pos=work/split[i]; + work=work%split[i]; + res[i]=pos; + } +} diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.hxx b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx new file mode 100644 index 000000000..80f18ec9f --- /dev/null +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#ifndef __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCOUPLING_EXPORT MEDCouplingStructuredMesh : public MEDCouplingMesh + { + public: + INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + std::set getAllGeoTypes() const; + int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + static void GetPosFromId(int nodeId, int meshDim, const int *split, int *res); + void getNodeIdsOfCell(int cellId, std::vector& conn) const; + std::size_t getHeapMemorySize() const; + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + //tools + std::vector getDistributionOfTypes() const throw(INTERP_KERNEL::Exception); + DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); + void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); + MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildOrthogonalField() const; + void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const; + //some useful methods + int getCellIdFromPos(int i, int j, int k) const; + int getNodeIdFromPos(int i, int j, int k) const; + virtual void getNodeGridStructure(int *res) const = 0; + virtual void getSplitCellValues(int *res) const = 0; + virtual void getSplitNodeValues(int *res) const = 0; + protected: + MEDCouplingStructuredMesh(); + MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy); + ~MEDCouplingStructuredMesh(); + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index 7712aa874..384615a3d 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -19,8 +19,9 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingMemArray.hxx" #include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMesh.hxx" #include #include @@ -92,6 +93,14 @@ void MEDCouplingTimeDiscretization::updateTime() const updateTimeWith(*_array); } +std::size_t MEDCouplingTimeDiscretization::getHeapMemorySize() const +{ + std::size_t ret=_time_unit.capacity(); + if(_array) + ret+=_array->getHeapMemorySize(); + return ret; +} + bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) @@ -813,6 +822,11 @@ std::string MEDCouplingNoTimeLabel::getStringRepr() const return stream.str(); } +void MEDCouplingNoTimeLabel::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::synchronizeTimeWith : impossible to synchronize time with a MEDCouplingMesh because the time discretization is incompatible with it !"); +} + bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *other) const { if(!MEDCouplingTimeDiscretization::areCompatible(other)) @@ -1177,6 +1191,17 @@ std::string MEDCouplingWithTimeStep::getStringRepr() const return stream.str(); } +void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _time=val; _iteration=it; _order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); @@ -1662,6 +1687,18 @@ std::string MEDCouplingConstOnTimeInterval::getStringRepr() const return stream.str(); } +void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _start_time=val; _start_iteration=it; _start_order=order; + _end_time=val; _end_iteration=it; _end_order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const { return new MEDCouplingConstOnTimeInterval(*this,deepCpy); @@ -2039,6 +2076,26 @@ void MEDCouplingTwoTimeSteps::updateTime() const updateTimeWith(*_end_array); } +void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _start_time=val; _start_iteration=it; _start_order=order; + _end_time=val; _end_iteration=it; _end_order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + +std::size_t MEDCouplingTwoTimeSteps::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_end_array) + ret+=_end_array->getHeapMemorySize(); + return MEDCouplingTimeDiscretization::getHeapMemorySize()+ret; +} + void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index 79d6fa07a..890316418 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -30,6 +30,7 @@ namespace ParaMEDMEM { + class MEDCouplingMesh; class DataArrayDouble; class TimeLabel; @@ -40,6 +41,7 @@ namespace ParaMEDMEM MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy); public: void updateTime() const; + virtual std::size_t getHeapMemorySize() const; static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); void setTimeUnit(const char *unit) { _time_unit=unit; } const char *getTimeUnit() const { return _time_unit.c_str(); } @@ -57,6 +59,7 @@ namespace ParaMEDMEM virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; virtual std::string getStringRepr() const = 0; virtual TypeOfTimeDiscretization getEnum() const = 0; + virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const = 0; virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; @@ -158,6 +161,7 @@ namespace ParaMEDMEM MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); std::string getStringRepr() const; TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; @@ -218,6 +222,7 @@ namespace ParaMEDMEM std::string getStringRepr() const; void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; @@ -300,6 +305,7 @@ namespace ParaMEDMEM void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); std::string getStringRepr() const; MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; @@ -350,6 +356,8 @@ namespace ParaMEDMEM ~MEDCouplingTwoTimeSteps(); public: void updateTime() const; + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); const DataArrayDouble *getEndArray() const; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index dae38283f..a34d71b80 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -26,6 +26,7 @@ #include "InterpolationUtils.hxx" #include "PointLocatorAlgos.txx" #include "BBTree.txx" +#include "SplitterTetra.hxx" #include "DirectedBoundingBox.hxx" #include "InterpKernelMeshQuality.hxx" #include "InterpKernelCellSimplify.hxx" @@ -46,8 +47,6 @@ using namespace ParaMEDMEM; -const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_"; - double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED }; @@ -75,6 +74,16 @@ MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const return new MEDCouplingUMesh(*this,recDeepCpy); } +std::size_t MEDCouplingUMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_nodal_connec) + ret+=_nodal_connec->getHeapMemorySize(); + if(_nodal_connec_index) + ret+=_nodal_connec_index->getHeapMemorySize(); + return MEDCouplingPointSet::getHeapMemorySize()+ret; +} + void MEDCouplingUMesh::updateTime() const { MEDCouplingPointSet::updateTime(); @@ -88,8 +97,7 @@ void MEDCouplingUMesh::updateTime() const } } -MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2), - _nodal_connec(0),_nodal_connec_index(0) +MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0) { } @@ -102,7 +110,9 @@ MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2), void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) { if(_mesh_dim<-1) - throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + if(_mesh_dim!=-1) + MEDCouplingPointSet::checkCoherency(); for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) { if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim) @@ -126,10 +136,6 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec_index->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); } - if(_iterator!=-1) - { - throw INTERP_KERNEL::Exception("It appears that finishInsertingCells method has not been invoked after a insertNextCell session !"); - } } /*! @@ -216,14 +222,11 @@ void MEDCouplingUMesh::allocateCells(int nbOfCells) { _nodal_connec->decrRef(); } - _nodal_connec_index=DataArrayInt::New(); - _nodal_connec_index->alloc(nbOfCells+1,1); - int *pt=_nodal_connec_index->getPointer(); - pt[0]=0; + _nodal_connec_index->reserve(nbOfCells+1); + _nodal_connec_index->pushBackSilent(0); _nodal_connec=DataArrayInt::New(); - _nodal_connec->alloc(2*nbOfCells,1); - _iterator=0; + _nodal_connec->reserve(2*nbOfCells); _types.clear(); declareAsNew(); } @@ -241,15 +244,18 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !"); if((int)cm.getDimension()==_mesh_dim) { - int nbOfElems=_nodal_connec_index->getNbOfElems()-1; - if(_iterator>=nbOfElems) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : allocation of cells was wide enough ! Call insertNextCell with higher value or call finishInsertingCells !"); - int *pt=_nodal_connec_index->getPointer(); - int idx=pt[_iterator]; - + if(!cm.isDynamic()) + if(size!=(int)cm.getNumberOfNodes()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : Trying to push a " << cm.getRepr() << " cell with a size of " << size; + oss << " ! Expecting " << cm.getNumberOfNodes() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int idx=_nodal_connec_index->back(); + int val=idx+size+1; + _nodal_connec_index->pushBackSilent(val); _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size); _types.insert(type); - pt[++_iterator]=idx+size+1; } else { @@ -265,12 +271,8 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in */ void MEDCouplingUMesh::finishInsertingCells() { - const int *pt=_nodal_connec_index->getConstPointer(); - int idx=pt[_iterator]; - - _nodal_connec->reAlloc(idx); - _nodal_connec_index->reAlloc(_iterator+1); - _iterator=-1; + _nodal_connec->pack(); + _nodal_connec_index->pack(); _nodal_connec->declareAsNew(); _nodal_connec_index->declareAsNew(); updateTime(); @@ -430,13 +432,9 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); if(pt!=da->getConstPointer()+da->getNbOfElems()) throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - MEDCouplingAutoRefCountObjectPtr cellCor2=DataArrayInt::New(); - cellCor2->alloc(otherC->getNumberOfCells(),1); - std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer()); - bool nident=nodeCor2->isIdentity(); - bool cident=cellCor2->isIdentity(); - if(!nident) { nodeCor=nodeCor2; nodeCor2->incrRef(); } else nodeCor=0; - if(!cident) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0; + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); + nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); } /*! @@ -471,10 +469,8 @@ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot { throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); } - MEDCouplingAutoRefCountObjectPtr cellCor2=DataArrayInt::New(); - cellCor2->alloc(otherC->getNumberOfCells(),1); - std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer()); - if(!cellCor2->isIdentity()) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0; + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); } /*! @@ -651,22 +647,19 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons MEDCouplingAutoRefCountObjectPtr out1=DataArrayInt::New(); out1->alloc(nbCells+1,1); int *out1Ptr=out1->getPointer(); *out1Ptr++=0; - std::vector out0v; - out0v.reserve(desc->getNumberOfTuples()); + out0->reserve(desc->getNumberOfTuples()); for(int i=0;i s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]); s.erase(i); - out0v.insert(out0v.end(),s.begin(),s.end()); + out0->insertAtTheEnd(s.begin(),s.end()); } - *out1Ptr=out0v.size(); + *out1Ptr=out0->getNumberOfTuples(); } - out0->alloc((int)out0v.size(),1); - std::copy(out0v.begin(),out0v.end(),out0->getPointer()); - neighbors=out0; out0->incrRef(); - neighborsIndx=out1; out1->incrRef(); + neighbors=out0.retn(); + neighborsIndx=out1.retn(); } /// @cond INTERNAL @@ -680,100 +673,108 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt checkConnectivityFullyDefined(); int nbOfCells=getNumberOfCells(); int nbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero(); + int *revNodalIndxPtr=revNodalIndx->getPointer(); const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); - std::vector< std::vector > descMeshConnB(nbOfCells); - std::vector< std::vector > revDescMeshConnB; - std::vector< std::vector > revNodalB(nbOfNodes); - std::vector meshDM1Conn; - std::vector meshDM1ConnIndex(1); meshDM1ConnIndex[0]=0; - std::vector meshDM1Type; - for(int eltId=0;eltId ret=MEDCouplingUMesh::New(name.c_str(),getMeshDimension()-1); + ret->setCoords(getCoords()); + ret->allocateCells(2*nbOfCells); + descIndx->alloc(nbOfCells+1,1); + MEDCouplingAutoRefCountObjectPtr revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells); + int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0; + for(int eltId=0;eltId tmp=new int[posP1-pos]; for(unsigned i=0;i shareableCells(revNodalB[tmp[0]].begin(),revNodalB[tmp[0]].end()); - for(unsigned j=1;j tmp2(revNodalB[tmp[j]].begin(),revNodalB[tmp[j]].end()); - std::set tmp3; - std::set_intersection(tmp2.begin(),tmp2.end(),shareableCells.begin(),shareableCells.end(),inserter(tmp3,tmp3.begin())); - shareableCells=tmp3; - } - std::list shareableCellsL(shareableCells.begin(),shareableCells.end()); - std::set ref(tmp,tmp+nbOfNodesSon); - for(std::list::iterator iter=shareableCellsL.begin();iter!=shareableCellsL.end();) - { - if(cms.isCompatibleWith((INTERP_KERNEL::NormalizedCellType)meshDM1Type[*iter])) - { - std::set ref2(meshDM1Conn.begin()+meshDM1ConnIndex[*iter],meshDM1Conn.begin()+meshDM1ConnIndex[(*iter)+1]); - if(ref==ref2) - break; - else - iter=shareableCellsL.erase(iter); - } - else - iter=shareableCellsL.erase(iter); - } - if(shareableCellsL.empty()) + for(unsigned k=0;k=0) + revNodalIndxPtr[tmp[k]+1]++; + ret->insertNextCell(cmsId,nbOfNodesSon,tmp); + revDesc2->pushBackSilent(eltId); + } + descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons; + } + int nbOfCellsM1=ret->getNumberOfCells(); + std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); + MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1); + std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1); + int *revNodalPtr=revNodal->getPointer(); + const int *connM1=ret->getNodalConnectivity()->getConstPointer(); + const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer(); + for(int eltId=0;eltId=0)//for polyhedrons + *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to(),-1))=eltId; + } + // + DataArrayInt *commonCells=0,*commonCellsI=0; + FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer()); + int newNbOfCellsM1=-1; + MEDCouplingAutoRefCountObjectPtr o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(), + commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1); + std::vector isImpacted(nbOfCellsM1,false); + for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++) + for(int work2=work[0];work2!=work[1];work2++) + isImpacted[commonCellsPtr[work2]]=true; + const int *o2nM1Ptr=o2nM1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1); + const int *n2oM1Ptr=n2oM1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret2=static_cast(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true)); + ret2->copyTinyInfoFrom(this); + desc->alloc(descIndx->back(),1); + int *descPtr=desc->getPointer(); + const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1); + for(int i=0;isetCoords(getCoords()); - int nbOfCellsInConstituent=(int)meshDM1Type.size(); - ret->allocateCells(nbOfCellsInConstituent); - revDescIndx->alloc(nbOfCellsInConstituent+1,1); - int *tmp3=revDescIndx->getPointer(); tmp3[0]=0; - for(int ii=0;iireserve(newNbOfCellsM1); + revDescIndx->alloc(newNbOfCellsM1+1,1); + int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0; + const int *revDesc2Ptr=revDesc2->getConstPointer(); + for(int i=0;iinsertNextCell((INTERP_KERNEL::NormalizedCellType)meshDM1Type[ii],meshDM1ConnIndex[ii+1]-meshDM1ConnIndex[ii],&meshDM1Conn[meshDM1ConnIndex[ii]]); - tmp3[ii+1]=tmp3[ii]+((int)revDescMeshConnB[ii].size()); + int oldCellIdM1=n2oM1Ptr[i]; + if(!isImpacted[oldCellIdM1]) + { + revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+1; + } + else + { + for(int j=commonCellsIPtr[0];jpushBackSilent(revDesc2Ptr[commonCellsPtr[j]]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0]; + commonCellsIPtr++; + } } - ret->finishInsertingCells(); - revDesc->alloc(tmp3[nbOfCellsInConstituent],1); - tmp3=revDesc->getPointer(); - for(std::vector< std::vector >::const_iterator iter2=revDescMeshConnB.begin();iter2!=revDescMeshConnB.end();iter2++) - tmp3=std::copy((*iter2).begin(),(*iter2).end(),tmp3); - meshDM1Type.clear(); meshDM1ConnIndex.clear(); meshDM1Conn.clear(); - descIndx->alloc(nbOfCells+1,1); - tmp3=descIndx->getPointer(); tmp3[0]=0; - for(int jj=0;jjalloc(tmp3[nbOfCells],1); - tmp3=desc->getPointer(); - for(std::vector< std::vector >::const_iterator iter3=descMeshConnB.begin();iter3!=descMeshConnB.end();iter3++) - tmp3=std::copy((*iter3).begin(),(*iter3).end(),tmp3); // - return ret; + return ret2.retn(); } struct MEDCouplingAccVisit @@ -962,9 +963,8 @@ void MEDCouplingUMesh::convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception else newc=std::copy(c+ci[i],c+ci[i+1],newc); } - _nodal_connec_index->decrRef(); _nodal_connec_index=newCi; - _nodal_connec->decrRef(); _nodal_connec=newC; - newC->incrRef(); newCi->incrRef(); + _nodal_connec_index->decrRef(); _nodal_connec_index=newCi.retn(); + _nodal_connec->decrRef(); _nodal_connec=newC.retn(); } /*! @@ -1069,7 +1069,7 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except MEDCouplingAutoRefCountObjectPtr connINew=DataArrayInt::New(); connINew->alloc(nbOfCells+1,1); int *connINewPtr=connINew->getPointer(); *connINewPtr++=0; - std::vector connNew; + MEDCouplingAutoRefCountObjectPtr connNew=DataArrayInt::New(); connNew->alloc(0,1); bool changed=false; for(int i=0;iinsertAtTheEnd(conn+index[i],conn+index[i+1]); + *connINewPtr=connNew->getNumberOfTuples(); } if(changed) - { - MEDCouplingAutoRefCountObjectPtr connNew2=DataArrayInt::New(); - connNew2->alloc((int)connNew.size(),1); - std::copy(connNew.begin(),connNew.end(),connNew2->getPointer()); - setConnectivity(connNew2,connINew,false); - } + setConnectivity(connNew,connINew,false); } /*! @@ -1102,20 +1097,53 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception) { checkConnectivityFullyDefined(); - std::set retS; int nbOfCells=getNumberOfCells(); const int *connIndex=_nodal_connec_index->getConstPointer(); const int *conn=_nodal_connec->getConstPointer(); + const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end()); + int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1; + std::vector retS(maxElt,false); for(int i=0;i=0) - retS.insert(conn[j]); + retS[conn[j]]=true; + int sz=0; + for(int i=0;ialloc((int)retS.size(),1); - std::copy(retS.begin(),retS.end(),ret->getPointer()); + ret->alloc(sz,1); + int *retPtr=ret->getPointer(); + for(int i=0;i& nodeIdsInUse) const throw(INTERP_KERNEL::Exception) +{ + int nbOfNodes=(int)nodeIdsInUse.size(); + int nbOfCells=getNumberOfCells(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + for(int i=0;i=0) + { + if(conn[j]= nb of nodes an exception will be thrown. + * \sa MEDCouplingUMesh::computeNodeIdsAlg */ DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception) { nbrOfNodesInUse=-1; int nbOfNodes=getNumberOfNodes(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1); int *traducer=ret->getPointer(); std::fill(traducer,traducer+nbOfNodes,-1); @@ -1139,10 +1169,18 @@ DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const thro for(int i=0;i=0) - traducer[conn[j]]=1; + { + if(conn[j]incrRef(); return ret; + return ret.retn(); } /*! @@ -1190,29 +1228,29 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Excepti * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. */ -int MEDCouplingUMesh::areCellsEqual(int cell1, int cell2, int compType) const +int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) { switch(compType) { case 0: - return areCellsEqual0(cell1,cell2); + return AreCellsEqual0(conn,connI,cell1,cell2); case 1: - return areCellsEqual1(cell1,cell2); + return AreCellsEqual1(conn,connI,cell1,cell2); case 2: - return areCellsEqual2(cell1,cell2); + return AreCellsEqual2(conn,connI,cell1,cell2); + case 3: + return AreCellsEqual3(conn,connI,cell1,cell2); case 7: - return areCellsEqual7(cell1,cell2); + return AreCellsEqual7(conn,connI,cell1,cell2); } - throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1 or 2."); + throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2 or 3."); } /*! * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0. */ -int MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const +int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) { - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0; return 0; @@ -1221,10 +1259,8 @@ int MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const /*! * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1. */ -int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const +int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) { - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); int sz=connI[cell1+1]-connI[cell1]; if(sz==connI[cell2+1]-connI[cell2]) { @@ -1237,18 +1273,17 @@ int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const if(dim!=1) { int sz1=2*(sz-1); - int *tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp); + INTERP_KERNEL::AutoPtr tmp=new int[sz1]; + int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); - delete [] tmp; + work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); return work!=tmp+sz1?1:0; } else return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3 } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual1 : not implemented yet for meshdim == 3 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !"); } } return 0; @@ -1257,10 +1292,8 @@ int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const /*! * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2. */ -int MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const +int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) { - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) { if(conn[connI[cell1]]==conn[connI[cell2]]) @@ -1273,13 +1306,25 @@ int MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const return 0; } +/*! + * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account ! + */ +int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2) +{ + if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) + { + std::set s1(conn+connI[cell1]+1,conn+connI[cell1+1]); + std::set s2(conn+connI[cell2]+1,conn+connI[cell2+1]); + return s1==s2?1:0; + } + return 0; +} + /*! * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 7. */ -int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const +int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) { - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); int sz=connI[cell1+1]-connI[cell1]; if(sz==connI[cell2+1]-connI[cell2]) { @@ -1292,29 +1337,20 @@ int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const if(dim!=1) { int sz1=2*(sz-1); - int *tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp); + INTERP_KERNEL::AutoPtr tmp=new int[sz1]; + int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); + work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); if(work!=tmp+sz1) - { - delete [] tmp; - return 1; - } + return 1; else { - std::reverse_iterator it1(tmp+sz1); - std::reverse_iterator it2(tmp); + std::reverse_iterator it1((int *)tmp+sz1); + std::reverse_iterator it2((int *)tmp); if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2) - { - delete [] tmp; - return 2; - } + return 2; else - { - delete [] tmp; - return 0; - } + return 0; } return work!=tmp+sz1?1:0; @@ -1340,7 +1376,7 @@ int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const } } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual7 : not implemented yet for meshdim == 3 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !"); } } return 0; @@ -1382,172 +1418,165 @@ bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int * If in 'candidates' pool -1 value is considered as an empty value. * WARNING this method returns only ONE set of result ! */ -bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const +bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) { - std::set cand(candidates.begin(),candidates.end()); - cand.erase(-1); - if(cand.size()<=1) + if(candidates.size()<1) return false; bool ret=false; - std::set::const_iterator iter=cand.begin(); + std::vector::const_iterator iter=candidates.begin(); int start=(*iter++); - for(;iter!=cand.end();iter++) + for(;iter!=candidates.end();iter++) { - int status=areCellsEqual(start,*iter,compType); + int status=AreCellsEqual(conn,connI,start,*iter,compType); if(status!=0) { if(!ret) { - result.push_back(start); + result->pushBackSilent(start); ret=true; } if(status==1) - result.push_back(*iter); + result->pushBackSilent(*iter); else - result.push_back(status==2?(*iter+1):-(*iter+1)); + result->pushBackSilent(status==2?(*iter+1):-(*iter+1)); } } return ret; } /*! - * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details. - * This method returns 2 values 'res' and 'resI'. - * If 'res' and 'resI' are not empty before calling this method they will be cleared before set. - * The format of 'res' and 'resI' is as explained here. - * resI.size()-1 is the number of set of cells equal. - * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n -void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const +void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) { - res.clear(); resI.clear(); - resI.push_back(0); - std::vector bbox; - int nbOfCells=getNumberOfCells(); - getBoundingBoxForBBTree(bbox); - double bb[2*SPACEDIM]; - double eps=getCaracteristicDimension(); - eps*=1.e-12; - BBTree myTree(&bbox[0],0,0,nbOfCells,-eps); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - const double *coords=getCoords()->getConstPointer(); - std::vector isFetched(nbOfCells); - for(int k=0;k revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); + getReverseNodalConnectivity(revNodal,revNodalI); + FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); +} + +void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, + DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1); + int nbOfCells=nodalI->getNumberOfTuples()-1; + commonCellsI->reserve(1); commonCellsI->pushBackSilent(0); + const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); + const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer(); + std::vector isFetched(nbOfCells,false); + if(startCellId==0) { - if(!isFetched[k]) + for(int i=0;i::max(); bb[2*j+1]=-std::numeric_limits::max(); } - for(const int *pt=conn+connI[k]+1;pt!=conn+connI[k+1];pt++) - if(*pt>-1) - { - for(int j=0;j(),-1)); + std::vector v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) { - bb[2*j]=std::min(bb[2*j],coords[SPACEDIM*(*pt)+j]); - bb[2*j+1]=std::max(bb[2*j+1],coords[SPACEDIM*(*pt)+j]); + v=v2; + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + std::vector::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); } - } - std::vector candidates1; - myTree.getIntersectingElems(bb,candidates1); - std::vector candidates; - for(std::vector::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++) - if(!isFetched[*iter]) - candidates.push_back(*iter); - if(areCellsEqualInPool(candidates,compType,res)) + if(v2.size()>1) + { + if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) + { + int pos=commonCellsI->back(); + commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); + for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) + isFetched[*it]=true; + } + } + } + } + } + else + { + for(int i=startCellId;i::const_iterator it=res.begin()+pos;it!=res.end();it++) - isFetched[*it]=true; + const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to(),-1)); + std::vector v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) + { + v=v2; + std::vector::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); + } + if(v2.size()>1) + { + if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) + { + int pos=commonCellsI->back(); + commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); + for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) + isFetched[*it]=true; + } + } } - isFetched[k]=true; } } + commonCellsArr=commonCells.retn(); + commonCellsIArr=commonCellsI.retn(); } /*! - * This method could potentially modify 'this'. This method merges cells if there are cells equal in 'this'. The comparison is specified by 'compType'. - * This method keeps the coordiantes of 'this'. + * This method could potentially modify \a this. This method merges cells if there are cells equal in \a this. The comparison is specified by \a compType. + * This method keeps the coordiantes of \a this. * - * @param compType input specifying the technique used to compare cells each other. + * \param [in] compType input specifying the technique used to compare cells each other. * - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy. * - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation) * and their type equal. For 1D mesh the policy 1 is equivalent to 0. * - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy * can be used for users not sensitive to orientation of cell - * @return the correspondance array old to new. + * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned + * \return the correspondance array old to new in a newly allocated array. * * \warning This method modifies can modify significantly the geometric type order in \a this. * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. */ -DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception) { - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); - std::vector commonCells; - std::vector commonCellsI; - switch(spaceDim) - { - case 3: - { - findCommonCellsBase<3>(compType,commonCells,commonCellsI); - break; - } - case 2: - { - findCommonCellsBase<2>(compType,commonCells,commonCellsI); - break; - } - case 1: - { - findCommonCellsBase<1>(compType,commonCells,commonCellsI); - break; - } - default: - throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3."); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - std::fill(retPtr,retPtr+nbOfCells,0); - const std::size_t nbOfTupleSmCells=commonCellsI.size()-1; - int id=-1; - std::vector cellsToKeep; - for(std::size_t i=0;i::const_iterator it=commonCells.begin()+commonCellsI[i];it!=commonCells.begin()+commonCellsI[i+1];it++) - retPtr[*it]=id; - id--; - } - id=0; - std::map m; - for(int i=0;i::const_iterator iter=m.find(val); - if(iter==m.end()) - { - m[val]=id; - retPtr[i]=id++; - cellsToKeep.push_back(i); - } - else - retPtr[i]=(*iter).second; - } - } - MEDCouplingUMesh *self=(MEDCouplingUMesh *)buildPartOfMySelf(&cellsToKeep[0],&cellsToKeep[0]+cellsToKeep.size(),true); + DataArrayInt *commonCells=0,*commonCellsI=0; + findCommonCells(compType,startCellId,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + int newNbOfCells=-1; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), + commonCellsI->end(),newNbOfCells); + MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); + MEDCouplingAutoRefCountObjectPtr self=static_cast(buildPartOfMySelf(ret2->begin(),ret2->end(),true)); setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true); - self->decrRef(); - return ret; + return ret.retn(); } /*! @@ -1564,8 +1593,16 @@ DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTE bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType); int nbOfCells=getNumberOfCells(); + static const int possibleCompType[]={0,1,2}; + if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int)) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : "; + std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator(oss," ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); arr=o2n->substr(nbOfCells); arr->setName(other->getName()); int tmp; @@ -1586,45 +1623,26 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - int spaceDim=mesh->getSpaceDimension(); - std::vector commonCells; - std::vector commonCellsI; - switch(spaceDim) - { - case 3: - { - findCommonCellsBase<3>(7,commonCells,commonCellsI); - break; - } - case 2: - { - findCommonCellsBase<2>(7,commonCells,commonCellsI); - break; - } - case 1: - { - findCommonCellsBase<1>(7,commonCells,commonCellsI); - break; - } - default: - throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3."); - } + DataArrayInt *commonCells=0,*commonCellsI=0; int thisNbCells=getNumberOfCells(); + mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer(); int otherNbCells=other->getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::New(); arr2->alloc(otherNbCells,1); arr2->fillWithZero(); int *arr2Ptr=arr2->getPointer(); - int nbOfCommon=(int)commonCellsI.size()-1; + int nbOfCommon=commonCellsI->getNumberOfTuples()-1; for(int i=0;i0?1:-1; - int val=std::abs(commonCells[j])-1; + int sig=commonCellsPtr[j]>0?1:-1; + int val=std::abs(commonCellsPtr[j])-1; if(val>=thisNbCells) arr2Ptr[val-thisNbCells]=sig*(start+1); } @@ -1633,8 +1651,7 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr arr2->setName(other->getName()); if(arr2->presenceOfValue(0)) return false; - arr=arr2; - arr2->incrRef(); + arr=arr2.retn(); return true; } @@ -1873,12 +1890,10 @@ void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDC DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const { - std::vector cellIdsKept; + DataArrayInt *cellIdsKept=0; fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cellIdsKept.size(),1); - std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer()); - return ret; + cellIdsKept->setName(getName()); + return cellIdsKept; } /*! @@ -1887,28 +1902,38 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *part * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not. * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept. * - * @param begin input start of array of node ids. - * @param end input end of array of node ids. - * @param fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in. - * @param cellIdsKept in/out array where all candidate cell ids are put at the end. + * \param [in] begin input start of array of node ids. + * \param [in] end input end of array of node ids. + * \param [in] fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in. + * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. */ -void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector& cellIdsKept) const +void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const { - std::set fastFinder(begin,end); + MEDCouplingAutoRefCountObjectPtr cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); + checkConnectivityFullyDefined(); + int tmp=-1; + int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1; + std::vector fastFinder(sz,false); + for(const int *work=begin;work!=end;work++) + if(*work>=0 && *workgetConstPointer(); const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); for(int i=0;i connOfCell(conn+connIndex[i]+1,conn+connIndex[i+1]); - connOfCell.erase(-1);//polyhedron separator - int refLgth=(int)connOfCell.size(); - std::set locMerge; - std::insert_iterator< std::set > it(locMerge,locMerge.begin()); - std::set_intersection(connOfCell.begin(),connOfCell.end(),fastFinder.begin(),fastFinder.end(),it); - if(((int)locMerge.size()==refLgth && fullyIn) || (locMerge.size()!=0 && !fullyIn)) - cellIdsKept.push_back(i); + int ref=0,nbOfHit=0; + for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++) + if(*work2>=0) + { + ref++; + if(fastFinder[*work2]) + nbOfHit++; + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); } + cellIdsKeptArr=cellIdsKept.retn(); } /*! @@ -1916,13 +1941,10 @@ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int */ DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const { - std::vector cellIdsKept; + DataArrayInt *cellIdsKept=0; fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cellIdsKept.size(),1); - std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer()); - ret->setName(getName()); - return ret; + cellIdsKept->setName(getName()); + return cellIdsKept; } /*! @@ -1933,9 +1955,10 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const i */ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const { - std::vector cellIdsKept; + DataArrayInt *cellIdsKept=0; fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[0]+cellIdsKept.size(),true); + MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); + return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); } /*! @@ -1990,32 +2013,32 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception) { checkFullyDefined(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - meshDM1->decrRef(); - desc->decrRef(); - descIndx->decrRef(); + MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); // - DataArrayInt *tmp=revDescIndx->deltaShiftIndex(); - DataArrayInt *faceIds=tmp->getIdsEqual(1); - tmp->decrRef(); - int nbOfFaces=faceIds->getNumberOfTuples(); - const int *faces=faceIds->getConstPointer(); - std::set ret; - for(const int *w=faces;w!=faces+nbOfFaces;w++) - ret.insert(revDesc->getIJ(revDescIndx->getIJ(*w,0),0)); - faceIds->decrRef(); + buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef(); + desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0; // - revDescIndx->decrRef(); - revDesc->decrRef(); + MEDCouplingAutoRefCountObjectPtr tmp=revDescIndx->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0; + const int *revDescPtr=revDesc->getConstPointer(); + const int *revDescIndxPtr=revDescIndx->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector ret1(nbOfCells,false); + int sz=0; + for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++) + if(!ret1[revDescPtr[revDescIndxPtr[*pt]]]) + { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; } // DataArrayInt *ret2=DataArrayInt::New(); - ret2->alloc((int)ret.size(),1); - std::copy(ret.begin(),ret.end(),ret2->getPointer()); + ret2->alloc(sz,1); + int *ret2Ptr=ret2->getPointer(); + sz=0; + for(std::vector::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++) + if(*it) + *ret2Ptr++=sz; ret2->setName("BoundaryCells"); return ret2; } @@ -2077,8 +2100,8 @@ void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSa MEDCouplingAutoRefCountObjectPtr s_renum1=DataArrayInt::Aggregate(s2_renum2,s1arr_renum1,0); s_renum1->sort(); // - s0arr->incrRef(); cellIdsRk0=s0arr; - s_renum1->incrRef(); cellIdsRk1=s_renum1; + cellIdsRk0=s0arr.retn(); + cellIdsRk1=s_renum1.retn(); } /*! @@ -2202,9 +2225,9 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); // - cellIdsNeededToBeRenum=cellsToModifyConn0_torenum; cellsToModifyConn0_torenum->incrRef(); - cellIdsNotModified=cellsToModifyConn1_torenum; cellsToModifyConn1_torenum->incrRef(); - nodeIdsToDuplicate=s3; s3->incrRef(); + cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn(); + cellIdsNotModified=cellsToModifyConn1_torenum.retn(); + nodeIdsToDuplicate=s3.retn(); } /*! @@ -2374,15 +2397,16 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INT * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be * added in 'elems' parameter. */ -void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const { + MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); if(getMeshDimension()==-1) { - elems.push_back(0); - return; + elems->pushBackSilent(0); + return elems.retn(); } int dim=getSpaceDimension(); - double* elem_bb=new double[2*dim]; + INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; const int* conn = getNodalConnectivity()->getConstPointer(); const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); const double* coords = getCoords()->getConstPointer(); @@ -2414,11 +2438,9 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std } } if (intersectsBoundingBox(elem_bb, bbox, dim, eps)) - { - elems.push_back(ielem); - } + elems->pushBackSilent(ielem); } - delete [] elem_bb; + return elems.retn(); } /*! @@ -2426,15 +2448,16 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be * added in 'elems' parameter. */ -void MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) { + MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); if(getMeshDimension()==-1) { - elems.push_back(0); - return; + elems->pushBackSilent(0); + return elems.retn(); } int dim=getSpaceDimension(); - double* elem_bb=new double[2*dim]; + INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; const int* conn = getNodalConnectivity()->getConstPointer(); const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); const double* coords = getCoords()->getConstPointer(); @@ -2465,12 +2488,10 @@ void MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundi } } } - if (intersectsBoundingBox(bbox, elem_bb, dim, eps)) - { - elems.push_back(ielem); - } + if(intersectsBoundingBox(bbox, elem_bb, dim, eps)) + elems->pushBackSilent(ielem); } - delete [] elem_bb; + return elems.retn(); } /*! @@ -2495,12 +2516,13 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co * The coordinates array is not considered here. * * \param [in] type the geometric type - * \return the + * \return cell ids in this having geometric type \a type. */ DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) { - std::vector v; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(0,1); checkConnectivityFullyDefined(); int nbCells=getNumberOfCells(); int mdim=getMeshDimension(); @@ -2512,12 +2534,9 @@ DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellT for(int i=0;ipushBackSilent(i); } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc((int)v.size(),1); - std::copy(v.begin(),v.end(),ret->getPointer()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -2680,8 +2699,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const } else ret->setCoords(_coords); - ret->incrRef(); - return ret; + return ret.retn(); } void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const @@ -2745,7 +2763,7 @@ void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connInd * Copy constructor. If 'deepCpy' is false 'this' is a shallow copy of other. * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied. */ -MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_iterator(-1),_mesh_dim(other._mesh_dim), +MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim), _nodal_connec(0),_nodal_connec_index(0), _types(other._types) { @@ -2800,10 +2818,7 @@ void MEDCouplingUMesh::checkConnectivityFullyDefined() const throw(INTERP_KERNEL int MEDCouplingUMesh::getNumberOfCells() const { if(_nodal_connec_index) - if(_iterator==-1) - return _nodal_connec_index->getNumberOfTuples()-1; - else - return _iterator; + return _nodal_connec_index->getNumberOfTuples()-1; else if(_mesh_dim==-1) return 1; @@ -2944,19 +2959,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int ret->setConnectivity(newConn,newConnI,false); ret->_types=types; ret->copyTinyInfoFrom(this); - std::string name(getName()); - std::size_t sz=strlen(PART_OF_NAME); - if(name.length()>=sz) - name=name.substr(0,sz); - if(name!=PART_OF_NAME) - { - std::ostringstream stream; stream << PART_OF_NAME << getName(); - ret->setName(stream.str().c_str()); - } - else - ret->setName(getName()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -3005,19 +3008,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin connRetArr->decrRef(); connIndexRetArr->decrRef(); ret->copyTinyInfoFrom(this); - std::string name(getName()); - std::size_t sz=strlen(PART_OF_NAME); - if(name.length()>=sz) - name=name.substr(0,sz); - if(name!=PART_OF_NAME) - { - std::ostringstream stream; stream << PART_OF_NAME << getName(); - ret->setName(stream.str().c_str()); - } - else - ret->setName(getName()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -3034,7 +3025,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const std::string name="MeasureOfMesh_"; name+=getName(); int nbelem=getNumberOfCells(); - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS); + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); field->setName(name.c_str()); DataArrayDouble* array=DataArrayDouble::New(); array->alloc(nbelem,1); @@ -3042,6 +3033,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const field->setArray(array) ; array->decrRef(); field->setMesh(const_cast(this)); + field->synchronizeTimeWithMesh(); if(getMeshDimension()!=-1) { int ipt; @@ -3145,7 +3137,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const { if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); DataArrayDouble *array=DataArrayDouble::New(); int nbOfCells=getNumberOfCells(); int nbComp=getMeshDimension()+1; @@ -3191,6 +3183,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const ret->setArray(array); array->decrRef(); ret->setMesh(this); + ret->synchronizeTimeWithSupport(); return ret; } @@ -3202,7 +3195,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *be { if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); DataArrayDouble *array=DataArrayDouble::New(); std::size_t nbelems=std::distance(begin,end); int nbComp=getMeshDimension()+1; @@ -3248,6 +3241,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *be ret->setArray(array); array->decrRef(); ret->setMesh(this); + ret->synchronizeTimeWithSupport(); return ret; } @@ -3261,7 +3255,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !"); if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); DataArrayDouble *array=DataArrayDouble::New(); int nbOfCells=getNumberOfCells(); int spaceDim=getSpaceDimension(); @@ -3279,6 +3273,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const ret->setArray(array); array->decrRef(); ret->setMesh(this); + ret->synchronizeTimeWithSupport(); return ret; } @@ -3305,7 +3300,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const dou if(candidates->empty()) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !"); std::vector nodes; - std::vector cellIds2D,cellIds1D; + DataArrayInt *cellIds1D=0; MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); subMesh->findNodesOnPlane(origin,vec,eps,nodes); MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(),desc2=DataArrayInt::New(); @@ -3314,34 +3309,29 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const dou MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3 revDesc2=0; revDescIndx2=0; - mDesc2->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds2D); MEDCouplingAutoRefCountObjectPtr mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 revDesc1=0; revDescIndx1=0; mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); + MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); // std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(std::vector::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++) + for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) cut3DCurve[*it]=-1; mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); std::vector< std::pair > cut3DSurf(mDesc2->getNumberOfCells()); AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(), mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - std::vector conn,connI,cellIds2; - connI.push_back(0); + MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); + connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1); subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2); - if(cellIds2.empty()) + if(cellIds2->empty()) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !"); MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3D",2); ret->setCoords(mDesc1->getCoords()); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer()); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer()); - ret->setConnectivity(c,cI,true); - cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size()); - ret->incrRef(); - return ret; + ret->setConnectivity(conn,connI,true); + cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); + return ret.retn(); } /*! @@ -3367,7 +3357,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const if(candidates->empty()) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !"); std::vector nodes; - std::vector cellIds1D; + DataArrayInt *cellIds1D=0; MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); subMesh->findNodesOnPlane(origin,vec,eps,nodes); MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); @@ -3376,9 +3366,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); + MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); // std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(std::vector::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++) + for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) cut3DCurve[*it]=-1; mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); int ncellsSub=subMesh->getNumberOfCells(); @@ -3386,7 +3377,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(), mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - std::vector conn,connI,cellIds2; connI.push_back(0); + MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0); + conn->alloc(0,1); const int *nodal=subMesh->getNodalConnectivity()->getConstPointer(); const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer(); for(int i=0;ipushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second); + connI->pushBackSilent(conn->getNumberOfTuples()); + cellIds2->pushBackSilent(i); } else { @@ -3406,25 +3398,20 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const int nbOfEdges=nodalI[cellId3DSurf+1]-offset; for(int j=0;jpushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]); + connI->pushBackSilent(conn->getNumberOfTuples()); + cellIds2->pushBackSilent(cellId3DSurf); } } } } - if(cellIds2.empty()) + if(cellIds2->empty()) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !"); MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3DSurf",1); ret->setCoords(mDesc1->getCoords()); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer()); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer()); - ret->setConnectivity(c,cI,true); - cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size()); - ret->incrRef(); - return ret; + ret->setConnectivity(conn,connI,true); + cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); + return ret.retn(); } /*! @@ -3444,7 +3431,7 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co double vec2[3]; vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1) double angle=acos(vec[2]/normm); - std::vector cellIds; + MEDCouplingAutoRefCountObjectPtr cellIds; double bbox[6]; if(angle>eps) { @@ -3454,19 +3441,15 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co mw->setCoords(coo); mw->getBoundingBox(bbox); bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - mw->getCellsInBoundingBox(bbox,eps,cellIds); + cellIds=mw->getCellsInBoundingBox(bbox,eps); } else { getBoundingBox(bbox); bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - getCellsInBoundingBox(bbox,eps,cellIds); + cellIds=getCellsInBoundingBox(bbox,eps); } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc((int)cellIds.size(),1); - std::copy(cellIds.begin(),cellIds.end(),ret->getPointer()); - ret->incrRef(); - return ret; + return cellIds.retn(); } /*! @@ -3538,6 +3521,134 @@ void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, f->decrRef(); } +/*! + * This method computes the distance from a point \a pt to \a this and the first \a cellId and \a nodeId in \a this corresponding to the returned distance. + * \a this is expected to be a mesh so that its space dimension is equal to its + * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. + * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). + * + * This method firstly find the closer node in \a this to the requested point whose coordinates are defined by [ \a ptBg, \a ptEnd ). Then for this node found + * the cells sharing this node (if any) are considered to find if the distance to these cell are smaller than the result found previously. If no cells are linked + * to the node that minimizes distance with the input point then -1 is returned in cellId. + * + * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this. + * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. + * + * \param [in] ptBg the start pointer (included) of the coordinates of the point + * \param [in] ptEnd the end pointer (not included) of the coordinates of the point + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. + * \return the positive value of the distance. + * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space + * dimension - 1. + * \sa DataArrayDouble::distanceToTuple + */ +double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const throw(INTERP_KERNEL::Exception) +{ + int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); + if(meshDim!=spaceDim-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !"); + if(meshDim!=2 && meshDim!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !"); + checkFullyDefined(); + if((int)std::distance(ptBg,ptEnd)!=spaceDim) + { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + nodeId=-1; + double ret0=_coords->distanceToTuple(ptBg,ptEnd,nodeId); + if(nodeId==-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : something wrong with nodes in this !"); + MEDCouplingAutoRefCountObjectPtr cellIds=getCellIdsLyingOnNodes(&nodeId,&nodeId+1,false); + switch(meshDim) + { + case 2: + { + distanceToPoint3DSurfAlg(ptBg,cellIds,ret0,cellId); + return ret0; + } + case 1: + { + distanceToPoint2DCurveAlg(ptBg,cellIds,ret0,cellId); + return ret0; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !"); + } + + return ret0; +} + + +/*! + * \param [in] pt the start pointer (included) of the coordinates of the point + * \param [in] cellIds + * \param [in,out] ret0 the min distance between \a this and the external input point + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. + * \sa MEDCouplingUMesh::distanceToPoint + */ +void MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception) +{ + const double *coords=_coords->getConstPointer(); + cellId=-1; + if(cellIds->empty()) + return; + const int *ptr=_nodal_connec->getConstPointer(); + const int *ptrI=_nodal_connec_index->getConstPointer(); + for(const int *zeCell=cellIds->begin();zeCell!=cellIds->end();zeCell++) + { + switch((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[*zeCell]]) + { + case INTERP_KERNEL::NORM_TRI3: + { + double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*ptr[ptrI[*zeCell]+1],coords+3*ptr[ptrI[*zeCell]+2],coords+3*ptr[ptrI[*zeCell]+3]); + if(tmpgetConstPointer(); + if(cellIds->empty()) + { cellId=-1; return; } + const int *ptr=_nodal_connec->getConstPointer(); + const int *ptrI=_nodal_connec_index->getConstPointer(); + for(const int *zeCell=cellIds->begin();zeCell!=cellIds->end();zeCell++) + { + switch((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[*zeCell]]) + { + case INTERP_KERNEL::NORM_SEG2: + { + double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*ptr[ptrI[*zeCell]+1],coords+2*ptr[ptrI[*zeCell]+2]); + if(tmp!=std::numeric_limits::max()) tmp=sqrt(tmp); + if(tmp nodalConnecIndexOut=DataArrayInt::New(); nodalConnecIndexOut->alloc(nbOfCells+1,1); - std::vector nodalConnecOut; + MEDCouplingAutoRefCountObjectPtr nodalConnecOut(DataArrayInt::New()); int *workIndexOut=nodalConnecIndexOut->getPointer(); *workIndexOut=0; const int *nodalConnecIn=_nodal_connec->getConstPointer(); const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer(); std::set types; - std::vector isChanged; + MEDCouplingAutoRefCountObjectPtr isChanged(DataArrayInt::New()); + isChanged->alloc(0,1); for(int i=0;igetNumberOfTuples(); if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut)) - isChanged.push_back(i); - types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut[pos]); - workIndexOut[1]=(int)nodalConnecOut.size(); + isChanged->pushBackSilent(i); + types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0)); + workIndexOut[1]=nodalConnecOut->getNumberOfTuples(); } - if(isChanged.empty()) + if(isChanged->empty()) return 0; - MEDCouplingAutoRefCountObjectPtr nodalConnecOut2=DataArrayInt::New(); - nodalConnecOut2->alloc((int)nodalConnecOut.size(),1); - std::copy(nodalConnecOut.begin(),nodalConnecOut.end(),nodalConnecOut2->getPointer()); - setConnectivity(nodalConnecOut2,nodalConnecIndexOut,false); + setConnectivity(nodalConnecOut,nodalConnecIndexOut,false); _types=types; - DataArrayInt *ret=DataArrayInt::New(); ret->alloc((int)isChanged.size(),1); - std::copy(isChanged.begin(),isChanged.end(),ret->getPointer()); - return ret; -} - -/*! - * This method is expected to be applied on a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. - * This method analyzes only linear extruded 3D cells (NORM_HEXA8,NORM_PENTA6,NORM_HEXGP12...) - * If some extruded cells does not fulfill the MED norm for extruded cells (first face of 3D cell should be oriented to the exterior of the 3D cell). - * Some viewers are very careful of that (SMESH), but ParaVis ignore that. - */ -void MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells(std::vector& cells) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="check3DCellsWellOriented detection works only for 3D cells !"; - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception(msg); - int spaceDim=getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception(msg); - // - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=getCoords()->getConstPointer(); - double vec0[3],vec1[3]; - for(int i=0;i tmp=new int[connI[i+1]-connI[i]-1]; - int nbOfNodes=cm.fillSonCellNodalConnectivity(0,conn+connI[i]+1,tmp); - INTERP_KERNEL::areaVectorOfPolygon(tmp,nbOfNodes,coo,vec0); - const double *pt0=coo+3*conn[connI[i]+1]; - const double *pt1=coo+3*conn[connI[i]+nbOfNodes+1]; - vec1[0]=pt0[0]-pt1[0]; vec1[1]=pt0[1]-pt1[1]; vec1[2]=pt0[2]-pt1[2]; - double dot=vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2]; - if(dot<0) - { - cells.push_back(i); - std::copy(conn+connI[i]+1,conn+connI[i+1],(int *)tmp); - for(int j=1;jgetConstPointer(); const double *coords=_coords->getConstPointer(); std::vector addCoo; - std::vector newConn; - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + std::vector newConn;//no direct DataArrayInt because interface with Geometric2D + MEDCouplingAutoRefCountObjectPtr newConnI(DataArrayInt::New()); newConnI->alloc(nbCells+1,1); int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0; @@ -4453,12 +4514,15 @@ void MEDCouplingUMesh::tessellate2DCurve(double eps) throw(INTERP_KERNEL::Except /*! * This methods modify this by converting each cells into simplex cell, that is too say triangle for meshdim==2 or tetra for meshdim==3. - * This cut into simplex is performed following the parameter 'policy'. This method so typically increases the number of cells of this. - * This method returns new2old array that specifies a each cell of 'this' after the call what was its id it comes. + * This cut into simplex is performed following the parameter \a policy. This method so typically increases the number of cells of \a this. + * This method \b keeps the number of nodes \b unchanged. That's why the splitting policy in 3D INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here. + * This method returns new2old newly allocated array that specifies a each cell of \a this after the call what was its id it comes. * - * The semantic of 'policy' parameter : + * The semantic of \a policy parameter : * - 1 only QUAD4. For QUAD4 the cut is done along 0-2 diagonal for QUAD4 * - 2 only QUAD4. For QUAD4 the cut is done along 1-3 diagonal for QUAD4 + * - PLANAR_FACE_5 only HEXA8. All HEXA8 are split into 5 TETRA4 + * - PLANAR_FACE_6 only HEXA8. All HEXA8 are split into 6 TETRA4 */ DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) { @@ -4468,8 +4532,12 @@ DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exce return simplexizePol0(); case 1: return simplexizePol1(); + case (int) INTERP_KERNEL::PLANAR_FACE_5: + return simplexizePlanarFace5(); + case (int) INTERP_KERNEL::PLANAR_FACE_6: + return simplexizePlanarFace6(); default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be 0 or 1 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); } } @@ -4491,26 +4559,129 @@ bool MEDCouplingUMesh::areOnlySimplexCells() const throw(INTERP_KERNEL::Exceptio } /*! - * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); + ret->alloc(nbOfCells+nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;idecrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); + ret->alloc(nbOfCells+nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;idecrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. */ -DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception) { - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !"); int nbOfCells=getNumberOfCells(); - DataArrayInt *ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) - { - ret->iota(0); - return ret; - } + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); + ret->alloc(nbOfCells+4*nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } int *retPt=ret->getPointer(); - DataArrayInt *newConn=DataArrayInt::New(); - DataArrayInt *newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21 int *pt=newConn->getPointer(); int *ptI=newConnI->getPointer(); ptI[0]=0; @@ -4518,16 +4689,15 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception) const int *ci=_nodal_connec_index->getConstPointer(); for(int i=0;idecrRef(); - _nodal_connec=newConn; + _nodal_connec=newConn.retn(); _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI; + _nodal_connec_index=newConnI.retn(); computeTypes(); updateTime(); - return ret; + return ret.retn(); } /*! - * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. */ -DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception) { - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !"); int nbOfCells=getNumberOfCells(); - DataArrayInt *ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) - { - ret->iota(0); - return ret; - } + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); + ret->alloc(nbOfCells+5*nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } int *retPt=ret->getPointer(); - DataArrayInt *newConn=DataArrayInt::New(); - DataArrayInt *newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+21*nbOfCutCells,1); int *pt=newConn->getPointer(); int *ptI=newConnI->getPointer(); ptI[0]=0; @@ -4574,16 +4741,15 @@ DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception) const int *ci=_nodal_connec_index->getConstPointer(); for(int i=0;idecrRef(); - _nodal_connec=newConn; + _nodal_connec=newConn.retn(); _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI; + _nodal_connec_index=newConnI.retn(); computeTypes(); updateTime(); - return ret; + return ret.retn(); } /*! @@ -4810,7 +4976,9 @@ void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cell /*! * This method tries to orient correctly polhedrons cells. - * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails. + * + * \throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails. + * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells */ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception) { @@ -4820,20 +4988,130 @@ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Excepti int *conn=_nodal_connec->getPointer(); const int *connI=_nodal_connec_index->getConstPointer(); const double *coordsPtr=_coords->getConstPointer(); - bool isModified=false; for(int i=0;igetPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=getCoords()->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr cells(DataArrayInt::New()); cells->alloc(0,1); + for(int i=0;ipushBackSilent(i); + } + } + } + return cells.retn(); +} + +/*! + * This method is a faster method to correct orientation of all 3D cells in \a this. + * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3. + * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception. + * + * \ret a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling) + * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, + */ +DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + int *conn=_nodal_connec->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); + for(int i=0;ipushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_PYRA5: + { + if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4)); + ret->pushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_PENTA6: + case INTERP_KERNEL::NORM_HEXA8: + case INTERP_KERNEL::NORM_HEXGP12: + { + if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]); + ret->pushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_POLYHED: { - TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); - isModified=true; + if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); + ret->pushBackSilent(i); + } + break; } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !"); + } } - if(isModified) - _nodal_connec->declareAsNew(); updateTime(); + return ret.retn(); } /*! @@ -4869,7 +5147,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !"); if(meshDim!=2 && meshDim!=3) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); int nbOfCells=getNumberOfCells(); DataArrayDouble *arr=DataArrayDouble::New(); @@ -4910,8 +5188,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP conn+=connI[i+1]-connI[i]; } ret->setName("EdgeRatio"); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -4929,7 +5207,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTE throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !"); if(meshDim!=2 && meshDim!=3) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); int nbOfCells=getNumberOfCells(); DataArrayDouble *arr=DataArrayDouble::New(); @@ -4970,8 +5248,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTE conn+=connI[i+1]-connI[i]; } ret->setName("AspectRatio"); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -4989,7 +5267,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERN throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !"); if(meshDim!=2) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); int nbOfCells=getNumberOfCells(); DataArrayDouble *arr=DataArrayDouble::New(); @@ -5018,8 +5296,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERN conn+=connI[i+1]-connI[i]; } ret->setName("Warp"); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -5037,7 +5315,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !"); if(meshDim!=2) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); int nbOfCells=getNumberOfCells(); DataArrayDouble *arr=DataArrayDouble::New(); @@ -5066,8 +5344,8 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN conn+=connI[i+1]-connI[i]; } ret->setName("Skew"); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -5376,8 +5654,7 @@ DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Ex checkConnectivityFullyDefined(); MEDCouplingAutoRefCountObjectPtr ret=getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); renumberCells(ret->getConstPointer(),false); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5402,6 +5679,17 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const return true; } +/*! + * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here. + * The geometric type order is specified by MED file. + * + * \sa MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder + */ +bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception) +{ + return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); +} + /*! * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check * that the order is specified in array defined by [orderBg,orderEnd). @@ -5460,10 +5748,8 @@ DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::Norma throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - nbPerType=tmpb; - tmpa->incrRef(); - tmpb->incrRef(); - return tmpa; + nbPerType=tmpb.retn(); + return tmpa.retn(); } /*! @@ -5584,8 +5870,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons std::vector m1ssmSingle; std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmSingleAuto; int fake=0,rk=0; - std::vector ret1Data; - std::vector ret2Data; + MEDCouplingAutoRefCountObjectPtr ret1(DataArrayInt::New()),ret2(DataArrayInt::New()); + ret1->alloc(0,1); ret2->alloc(0,1); for(std::vector::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++) { if(meshDim!=(*it)->getMeshDimension()) @@ -5600,11 +5886,9 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons MEDCouplingUMesh *singleCell=static_cast((*it2)->buildPartOfMySelf(&fake,&fake+1,true)); m1ssmSingleAuto.push_back(singleCell); m1ssmSingle.push_back(singleCell); - ret1Data.push_back((*it2)->getNumberOfCells()); ret2Data.push_back(rk); + ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk); } } - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc((int)m1ssmSingle.size(),1); std::copy(ret1Data.begin(),ret1Data.end(),ret1->getPointer()); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)m1ssmSingle.size(),1); std::copy(ret2Data.begin(),ret2Data.end(),ret2->getPointer()); MEDCouplingAutoRefCountObjectPtr m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle); MEDCouplingAutoRefCountObjectPtr renum=m1ssmSingle2->sortCellsInMEDFileFrmt(); std::vector m1ssmfinal(m1ssm.size()); @@ -5613,8 +5897,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons MEDCouplingAutoRefCountObjectPtr ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal); szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer()); idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer()); - ret0->incrRef(); - return ret0; + return ret0.retn(); } /*! @@ -5624,16 +5907,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception) { checkFullyDefined(); - std::vector r; const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(const int *w=begin;w!=end;w++) if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type) - r.push_back(*w); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(*w); + return ret.retn(); } /*! @@ -5706,8 +5986,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized } MEDCouplingAutoRefCountObjectPtr ret=static_cast(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true)); ret->copyTinyInfoFrom(this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5747,13 +6026,12 @@ MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) */ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const { - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int spaceDim=getSpaceDimension(); int nbOfCells=getNumberOfCells(); ret->alloc(nbOfCells,spaceDim); ret->copyStringInfoFrom(*getCoords()); double *ptToFill=ret->getPointer(); - double *tmp=new double[spaceDim]; const int *nodal=_nodal_connec->getConstPointer(); const int *nodalI=_nodal_connec_index->getConstPointer(); const double *coor=_coords->getConstPointer(); @@ -5763,8 +6041,7 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const INTERP_KERNEL::computeBarycenter2(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill); ptToFill+=spaceDim; } - delete [] tmp; - return ret; + return ret.retn(); } /*! @@ -5819,8 +6096,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da) t *cip++=2*(i+1); } ret->setConnectivity(c,cI,true); - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5928,8 +6204,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vectorsetConnectivity(c,cI,true); c->decrRef(); cI->decrRef(); - ret->incrRef(); - return ret; + return ret.retn(); } /// @endcond @@ -6135,7 +6410,7 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector tmp1(comm),tmp2(commI); int oldNbOfNodes=coo->getNumberOfTuples(); int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes); if(oldNbOfNodes==newNbOfNodes) return ; MEDCouplingAutoRefCountObjectPtr newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); @@ -6271,6 +6546,58 @@ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end return INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION; } +/*! + * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [begin,end). + */ +bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords) +{ + double vec0[3],vec1[3]; + std::size_t sz=std::distance(begin,end); + if(sz%2!=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !"); + int nbOfNodes=(int)sz/2; + INTERP_KERNEL::areaVectorOfPolygon(begin,nbOfNodes,coords,vec0); + const double *pt0=coords+3*begin[0]; + const double *pt1=coords+3*begin[nbOfNodes]; + vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2]; + return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.; +} + +void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end) +{ + std::size_t sz=std::distance(begin,end); + INTERP_KERNEL::AutoPtr tmp=new int[sz]; + std::size_t nbOfNodes(sz/2); + std::copy(begin,end,(int *)tmp); + for(std::size_t j=1;j(begin,4,coords,vec0); + const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4]; + return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.; +} + /*! * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [\b begin, \b end) * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to @@ -6280,9 +6607,9 @@ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end * \param [in] coords the coordinates with nb of components exactly equal to 3 * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded) - * \param [out] the result is put at the end of the vector without any alteration of the data. + * \param [out] res the result is put at the end of the vector without any alteration of the data. */ -void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, std::vector& res) throw(INTERP_KERNEL::Exception) +void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) throw(INTERP_KERNEL::Exception) { int nbFaces=std::count(begin+1,end,-1)+1; MEDCouplingAutoRefCountObjectPtr v=DataArrayDouble::New(); v->alloc(nbFaces,3); @@ -6303,7 +6630,7 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble const int *comm1Ptr=comm1->getConstPointer(); const int *commI1Ptr=commI1->getConstPointer(); int nbOfGrps1=commI1Auto->getNumberOfTuples()-1; - res.push_back((int)INTERP_KERNEL::NORM_POLYHED); + res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED); // MEDCouplingAutoRefCountObjectPtr mm=MEDCouplingUMesh::New("",3); mm->setCoords(const_cast(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1); @@ -6323,8 +6650,8 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble { if(commI2Ptr[j+1]-commI2Ptr[j]<=1) { - res.insert(res.end(),begin,end); - res.push_back(-1); + res->insertAtTheEnd(begin,end); + res->pushBackSilent(-1); } else { @@ -6354,13 +6681,13 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble { int l=0; for(const int *work=conn4+connI4[k]+1;work!=conn4+connI4[k+1];work++,l++) - res.push_back(idsNodePtr[*work]); - res.push_back(-1); + res->pushBackSilent(idsNodePtr[*work]); + res->pushBackSilent(-1); } } } } - res.pop_back(); + res->popBackSilent(); } /*! @@ -6422,52 +6749,70 @@ void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, c */ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception) { - std::vector > edges; + std::list< std::pair > edgesOK,edgesFinished; std::size_t nbOfFaces=std::count(begin,end,-1)+1; - int *bgFace=begin; - std::vector isPerm(nbOfFaces); - for(std::size_t i=0;i isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented + isPerm[0]=true; + int *bgFace=begin,*endFace=std::find(begin+1,end,-1); + std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); + for(std::size_t l=0;l p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); } + // + while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end()) { - int *endFace=std::find(bgFace+1,end,-1); - std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); - for(std::size_t l=0;l p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); - edges.push_back(p1); - } - int *bgFace2=endFace+1; - for(std::size_t k=i+1;k p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]); - if(std::find(edges.begin(),edges.end(),p2)!=edges.end()) + bool b; + for(std::size_t j=0;j tmp(nbOfEdgesInFace2-1); - std::copy(bgFace2+1,endFace2,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),bgFace2+1); - isPerm[k]=true; - continue; + std::pair p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + std::pair p2(p1.second,p1.first); + bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end(); + bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end(); + if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; } + } + if(isPerm[i]) + { + if(!b) + std::reverse(bgFace+1,endFace); + for(std::size_t j=0;j p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + std::pair p2(p1.second,p1.first); + if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end()) + { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end()) + { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + std::list< std::pair >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2); + if(it!=edgesOK.end()) + { + edgesOK.erase(it); + edgesFinished.push_back(p1); + } + else + edgesOK.push_back(p1); + } } } - bgFace2=endFace2+1; + bgFace=endFace+1; } - bgFace=endFace+1; + if(smthChanged==0) + { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); } } + if(!edgesOK.empty()) + { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); } if(INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION) {//not lucky ! The first face was not correctly oriented : reorient all faces... bgFace=begin; for(std::size_t i=0;i tmp(nbOfEdgesInFace-1); - std::copy(bgFace+1,endFace,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),bgFace+1); + endFace=std::find(bgFace+1,end,-1); + std::reverse(bgFace+1,endFace); bgFace=endFace+1; } } @@ -6498,7 +6843,7 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const throw(INTERP_KERNEL:: MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1); int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYGON; if(nbOfNodesExpected<1) - { ret->incrRef(); return ret; } + return ret.retn(); int prevCell=0; int prevNode=nodalPtr[nodalIPtr[0]+1]; *work++=n2oPtr[prevNode]; @@ -6528,7 +6873,7 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const throw(INTERP_KERNEL:: else throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !"); } - ret->incrRef(); return ret; + return ret.retn(); } /*! @@ -6548,15 +6893,14 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const throw(INTERP_KERNEL:: MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1); int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYHED; if(nbOfCells<1) - { ret->incrRef(); return ret; } + return ret.retn(); work=std::copy(conn+connI[0]+1,conn+connI[1],work); for(int i=1;iincrRef(); - return ret; + return ret.retn(); } /*! @@ -6687,8 +7031,8 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1 std::vector< std::vector > intersectEdge2; BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2); subDiv2.clear(); dd5=0; dd6=0; - std::vector cr,crI; - std::vector cNb1,cNb2; + std::vector cr,crI; //no DataArrayInt because interface with Geometric2D + std::vector cNb1,cNb2; //no DataArrayInt because interface with Geometric2D BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo, /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2); // @@ -6704,12 +7048,12 @@ MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1 MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Intersect2D",2); MEDCouplingAutoRefCountObjectPtr conn=DataArrayInt::New(); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer()); MEDCouplingAutoRefCountObjectPtr connI=DataArrayInt::New(); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer()); - MEDCouplingAutoRefCountObjectPtr c1=DataArrayInt::New(); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); cellNb1=c1; - MEDCouplingAutoRefCountObjectPtr c2=DataArrayInt::New(); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); cellNb2=c2; + MEDCouplingAutoRefCountObjectPtr c1=DataArrayInt::New(); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); + MEDCouplingAutoRefCountObjectPtr c2=DataArrayInt::New(); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); ret->setConnectivity(conn,connI,true); ret->setCoords(coo); - ret->incrRef(); c1->incrRef(); c2->incrRef(); - return ret; + cellNb1=c1.retn(); cellNb2=c2.retn(); + return ret.retn(); } /// @endcond @@ -6776,7 +7120,15 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo } if(!edges1.empty()) { - INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2); + try + { + INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } for(std::map::const_iterator it=mappRev.begin();it!=mappRev.end();it++) (*it).second->decrRef(); @@ -6985,7 +7337,7 @@ void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3D */ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, const int *desc, const int *descIndx, - std::vector& nodalRes, std::vector& nodalResIndx, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) + DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const throw(INTERP_KERNEL::Exception) { checkFullyDefined(); if(getMeshDimension()!=3 || getSpaceDimension()!=3) @@ -7051,9 +7403,9 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair3) { - nodalRes.insert(nodalRes.end(),conn.begin(),conn.end()); - nodalResIndx.push_back((int)nodalRes.size()); - cellIds.push_back(i); + nodalRes->insertAtTheEnd(conn.begin(),conn.end()); + nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples()); + cellIds->pushBackSilent(i); } } } @@ -7067,7 +7419,7 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair& nodalConnecOut) throw(INTERP_KERNEL::Exception) +bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) throw(INTERP_KERNEL::Exception) { std::size_t sz=std::distance(nodalConnBg,nodalConnEnd); if(sz>=4) @@ -7133,18 +7485,18 @@ bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, co std::copy(nodalConnBg+1,nodalConnEnd,it); if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end()) { - nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd); + nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); return false; } if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend()) { - nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd); + nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); return false; } else { - nodalConnecOut.push_back((int)INTERP_KERNEL::NORM_POLYGON); - nodalConnecOut.insert(nodalConnecOut.end(),tmpOut.begin(),tmpOut.end()); + nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON); + nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end()); return true; } } @@ -7178,7 +7530,7 @@ bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, cons *arrIPtr++=0; int previousArrI=0; const int *arrPtr=arr->getConstPointer(); - std::vector arrOut; + std::vector arrOut;//no utility to switch to DataArrayInt because copy always needed for(int i=0;ioffsetForRemoval) @@ -7261,10 +7613,8 @@ void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - arrOut=arro; - arrIndexOut=arrIo; - arro->incrRef(); - arrIo->incrRef(); + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); } /*! @@ -7331,8 +7681,8 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const in *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]); } } - arrOut=arro; arro->incrRef(); - arrIndexOut=arrIo; arrIo->incrRef(); + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); } /*! @@ -7389,41 +7739,86 @@ void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, c * \param [in] arrIn arr origin array from which the extraction will be done. * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. + * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone */ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) { - if(!arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); + int seed=0,nbOfDepthPeelingPerformed=0; + return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed); +} + +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn. + * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method. + * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. + * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. + * A negative value in \b arrIn means that it is ignored. + * This method is usefull to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. + * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone + * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit. + * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. + * \sa MEDCouplingUMesh::partitionBySpreadZone + */ +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception) +{ + nbOfDepthPeelingPerformed=0; + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !"); int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; if(nbOfTuples<=0) { DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1); return ret; } - const int *arrInPtr=arrIn->getConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - arro->alloc(nbOfTuples,1); - arro->fillWithValue(-1); - int *arroPtr=arro->getPointer(); - std::set s; s.insert(0); - while(!s.empty()) + // + std::vector fetched(nbOfTuples,false); + return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); +} + +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception) +{ + nbOfDepthPeelingPerformed=0; + if(!seedBg || !seedEnd || !arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + std::vector fetched2(nbOfTuples,false); + int i=0; + for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++) { - std::set s2; - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - { - for(const int *work=arrInPtr+arrIndxPtr[*it];work!=arrInPtr+arrIndxPtr[*it+1];work++) - { - if(*work>=0 && arroPtr[*work]<0) - { - arroPtr[*work]=1; - s2.insert(*work); - } - } - } - s=s2; + if(*seedElt>=0 && *seedEltgetIdsEqual(1); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits::max(); + std::vector idsToFetch1(seedBg,seedEnd); + std::vector idsToFetch2; + std::vector *idsToFetch=&idsToFetch1; + std::vector *idsToFetchOther=&idsToFetch2; + while(!idsToFetch->empty() && nbOfDepthPeelingPerformed::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++) + for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++) + if(!fetched[*it2]) + { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); } + std::swap(idsToFetch,idsToFetchOther); + idsToFetchOther->clear(); + nbOfDepthPeelingPerformed++; + } + int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true); + i=0; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(lgth,1); + int *retPtr=ret->getPointer(); + for(std::vector::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++) + if(*it) + *retPtr++=i; + return ret.retn(); } /*! @@ -7489,8 +7884,8 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, con *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]); } } - arrOut=arro; arro->incrRef(); - arrIndexOut=arrIo; arrIo->incrRef(); + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); } /*! @@ -7582,7 +7977,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER } // ret->finishInsertingCells(); - ret->incrRef(); return ret; + return ret.retn(); } /*! @@ -7592,6 +7987,28 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER */ std::vector MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception) { + //#if 0 + int nbOfCellsCur=getNumberOfCells(); + std::vector ret; + if(nbOfCellsCur<=0) + return ret; + DataArrayInt *neigh=0,*neighI=0; + computeNeighborsOfCells(neigh,neighI); + MEDCouplingAutoRefCountObjectPtr neighAuto(neigh),neighIAuto(neighI); + std::vector fetchedCells(nbOfCellsCur,false); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret2; + int seed=0; + while(seed >::iterator it=ret2.begin();it!=ret2.end();it++) + ret.push_back((*it).retn()); + return ret; + //#endif +#if 0 int nbOfCellsCur=getNumberOfCells(); DataArrayInt *neigh=0,*neighI=0; computeNeighborsOfCells(neigh,neighI); @@ -7619,6 +8036,7 @@ std::vector MEDCouplingUMesh::partitionBySpreadZone() const thro for(std::vector::const_iterator it=ret.begin();it!=ret.end();it++) (*it)->incrRef(); return ret; +#endif } /*! @@ -7642,8 +8060,7 @@ DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vec retPtr[0]=code[3*i+2]; retPtr[1]=code[3*i+2]+code[3*i+1]; } - ret->incrRef(); - return ret; + return ret.retn(); } MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 7da64ee50..c97142d8c 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -42,6 +42,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const; MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; } MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; @@ -91,11 +92,12 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception); //tools - MEDCOUPLING_EXPORT int areCellsEqual(int cell1, int cell2, int compType) const; - MEDCOUPLING_EXPORT int areCellsEqual0(int cell1, int cell2) const; - MEDCOUPLING_EXPORT int areCellsEqual1(int cell1, int cell2) const; - MEDCOUPLING_EXPORT int areCellsEqual2(int cell1, int cell2) const; - MEDCOUPLING_EXPORT int areCellsEqual7(int cell1, int cell2) const; + MEDCOUPLING_EXPORT static int AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); + MEDCOUPLING_EXPORT static int AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const; MEDCOUPLING_EXPORT void convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); MEDCOUPLING_EXPORT void convertAllToPoly(); @@ -106,9 +108,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::vector partitionBySpreadZone() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception); @@ -142,8 +146,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const; - MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems); + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCOUPLING_EXPORT DataArrayDouble *getPartMeasureField(bool isAbs, const int *begin, const int *end) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; @@ -155,12 +159,14 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isContiguous1D() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const; + MEDCOUPLING_EXPORT double distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; MEDCOUPLING_EXPORT void checkButterflyCells(std::vector& cells, double eps=1e-12) const; MEDCOUPLING_EXPORT DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void findAndCorrectBadOriented3DExtrudedCells(std::vector& cells) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getBoundingBoxForBBTree(std::vector& bbox) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); MEDCOUPLING_EXPORT bool isFullyQuadratic() const; @@ -188,6 +194,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingUMesh *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; + MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; MEDCOUPLING_EXPORT DataArrayInt *getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const throw(INTERP_KERNEL::Exception); @@ -214,11 +221,15 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, std::vector& res) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static bool Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static void CorrectExtrudedStaticCell(int *begin, int *end); + MEDCOUPLING_EXPORT static bool IsTetra4WellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static bool IsPyra5WellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector& nodalConnecOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); @@ -233,6 +244,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, + DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) throw(INTERP_KERNEL::Exception); private: MEDCouplingUMesh(); MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); @@ -243,17 +257,17 @@ namespace ParaMEDMEM //tools DataArrayInt *simplexizePol0() throw(INTERP_KERNEL::Exception); DataArrayInt *simplexizePol1() throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePlanarFace5() throw(INTERP_KERNEL::Exception); + DataArrayInt *simplexizePlanarFace6() throw(INTERP_KERNEL::Exception); void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) throw(INTERP_KERNEL::Exception); - void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector& cellIdsKept) const; + void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve) throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); - template - void findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const; - bool areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const; + static bool AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; template @@ -265,6 +279,9 @@ namespace ParaMEDMEM MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception); DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception); DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); + void distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception); + void distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const throw(INTERP_KERNEL::Exception); + static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) throw(INTERP_KERNEL::Exception); static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception); static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, @@ -281,21 +298,17 @@ namespace ParaMEDMEM const int *nodal3DCurve, const int *nodalIndx3DCurve, const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf) throw(INTERP_KERNEL::Exception); void assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, - const int *desc, const int *descIndx, std::vector& nodalRes, std::vector& nodalResIndx, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); + const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const throw(INTERP_KERNEL::Exception); public: MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24; MEDCOUPLING_EXPORT static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N_MEDMEM_ORDER]; /// @endcond private: - //! this iterator stores current position in _nodal_connec array. - mutable int _iterator; int _mesh_dim; DataArrayInt *_nodal_connec; DataArrayInt *_nodal_connec_index; std::set _types; - private: - static const char PART_OF_NAME[]; public: static double EPS_FOR_POLYH_ORIENTATION; }; diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 22905de85..998a2a043 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -21,6 +21,7 @@ #include "MEDCouplingUMeshDesc.hxx" #include "CellModel.hxx" #include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include #include @@ -57,6 +58,21 @@ MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New(const char *meshName, int meshDi return ret; } +std::size_t MEDCouplingUMeshDesc::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_desc_connec) + ret+=_desc_connec->getHeapMemorySize(); + if(_desc_connec_index) + ret+=_desc_connec_index->getHeapMemorySize(); + if(_nodal_connec_face) + ret+=_nodal_connec_face->getHeapMemorySize(); + if(_nodal_connec_face_index) + ret+=_nodal_connec_face_index->getHeapMemorySize(); + return MEDCouplingPointSet::getHeapMemorySize()+ret; +} + + MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const { throw INTERP_KERNEL::Exception("Not implemented yet !"); @@ -266,8 +282,9 @@ void MEDCouplingUMeshDesc::unserialization(const std::vector& tinyInfoD, setMeshDimension(tinyInfo[2]); } -void MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const +DataArrayInt *MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps) const { + MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); int dim=getSpaceDimension(); double* elem_bb=new double[2*dim]; const int* conn = _desc_connec->getConstPointer(); @@ -303,16 +320,16 @@ void MEDCouplingUMeshDesc::getCellsInBoundingBox(const double *bbox, double eps, } } } - if (intersectsBoundingBox(elem_bb, bbox, dim, eps)) - { - elems.push_back(ielem); - } + if(intersectsBoundingBox(elem_bb, bbox, dim, eps)) + elems->pushBackSilent(ielem); } delete [] elem_bb; + return elems.retn(); } -void MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& elems) +DataArrayInt *MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps) { + MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); int dim=getSpaceDimension(); double* elem_bb=new double[2*dim]; const int* conn = _desc_connec->getConstPointer(); @@ -349,11 +366,10 @@ void MEDCouplingUMeshDesc::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBo } } if (intersectsBoundingBox(bbox, elem_bb, dim, eps)) - { - elems.push_back(ielem); - } + elems->pushBackSilent(ielem); } delete [] elem_bb; + return elems.retn(); } DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index 37e27e1f3..18d3eb74a 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -34,6 +34,7 @@ namespace ParaMEDMEM public: MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(); MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim); + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); @@ -65,8 +66,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); - MEDCOUPLING_EXPORT void getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const; - MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& elems); + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/Makefile.am b/src/MEDCoupling/Makefile.am index 2434ecf7d..4202fab88 100644 --- a/src/MEDCoupling/Makefile.am +++ b/src/MEDCoupling/Makefile.am @@ -39,7 +39,7 @@ MEDCouplingUMeshDesc.hxx MEDCouplingNatureOfField.hxx MEDCouplingFieldTemplate.h MEDCouplingNormalizedCartesianMesh.hxx MEDCouplingNormalizedCartesianMesh.txx \ MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx MEDCouplingGaussLocalization.hxx \ MEDCouplingAutoRefCountObjectPtr.hxx MEDCouplingMultiFields.hxx MEDCouplingDefinitionTime.hxx \ -MEDCouplingFieldOverTime.hxx +MEDCouplingFieldOverTime.hxx MEDCouplingCurveLinearMesh.hxx MEDCouplingStructuredMesh.hxx # Libraries targets @@ -51,7 +51,8 @@ dist_libmedcoupling_la_SOURCES = \ MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx MEDCouplingFieldTemplate.cxx \ MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx MEDCouplingGaussLocalization.cxx \ MEDCouplingNatureOfField.cxx MEDCouplingMultiFields.cxx \ - MEDCouplingDefinitionTime.cxx MEDCouplingFieldOverTime.cxx + MEDCouplingDefinitionTime.cxx MEDCouplingFieldOverTime.cxx \ + MEDCouplingCurveLinearMesh.cxx MEDCouplingStructuredMesh.cxx libmedcoupling_la_LDFLAGS= diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index 9a55bea57..c26bbe173 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -581,7 +581,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf() CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(mesh->getAllTypes().begin()))); CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllTypes().size()); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllTypes().begin()); - CPPUNIT_ASSERT(name=="PartOf_Toto"); + CPPUNIT_ASSERT(name=="Toto"); CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); const int subConn[10]={4,0,3,4,1,4,7,8,5,4}; @@ -599,7 +599,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf() CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllTypes().size()); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllTypes().begin()); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(subMesh->getAllTypes().begin()))); - CPPUNIT_ASSERT(name=="PartOf_Toto"); + CPPUNIT_ASSERT(name=="Toto"); CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); const int subConn2[14]={4,0,3,4,1,3,4,5,2,4,6,7,4,3}; @@ -612,7 +612,7 @@ void MEDCouplingBasicsTest1::testBuildPartOfMySelf() MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true); subMesh->decrRef(); name=subMeshSimple2->getName(); - CPPUNIT_ASSERT(name=="PartOf_Toto"); + CPPUNIT_ASSERT(name=="Toto"); subMeshSimple2->decrRef(); // mesh->decrRef(); @@ -1364,7 +1364,7 @@ void MEDCouplingBasicsTest1::testMergeField1() std::string name=f3->getName(); CPPUNIT_ASSERT(name=="MeasureOfMesh_"); CPPUNIT_ASSERT(f3->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(7,f3->getNumberOfTuples()); double values[7]={0.25,0.125,0.125,0.25,0.25,0.5,0.5}; @@ -1410,10 +1410,15 @@ bool func3(const double *pt, double *res) void MEDCouplingBasicsTest1::testFillFromAnalytic() { MEDCouplingUMesh *m=build2DTargetMesh_1(); + m->setTime(3.4,5,6); m->setTimeUnit("us"); + int a,b; MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,func1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; @@ -1427,7 +1432,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic() f1=m->fillFromAnalytic(ON_NODES,1,func1); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values2[9]={-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4}; @@ -1441,7 +1446,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic() f1=m->fillFromAnalytic(ON_NODES,2,func2); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; @@ -1470,7 +1475,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2() MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,"y+x"); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; @@ -1484,7 +1489,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2() f1=m->fillFromAnalytic(ON_NODES,1,"y+2*x"); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; @@ -1497,7 +1502,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2() f1=m->fillFromAnalytic(ON_NODES,1,"2.*x+y"); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); tmp=f1->getArray()->getConstPointer(); @@ -1511,7 +1516,7 @@ void MEDCouplingBasicsTest1::testFillFromAnalytic2() f1=m->fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; @@ -1540,12 +1545,12 @@ void MEDCouplingBasicsTest1::testApplyFunc() MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); f1->applyFunc(1,func1); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; @@ -1564,7 +1569,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2() MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); // @@ -1574,7 +1579,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2() CPPUNIT_ASSERT_THROW(f2->applyFunc("a/0"),INTERP_KERNEL::Exception); f2->applyFunc("abs(u)^2.4+2*u"); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values2[18]={-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, @@ -1591,7 +1596,7 @@ void MEDCouplingBasicsTest1::testApplyFunc2() // f1->applyFunc(1,"x+y"); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; @@ -1614,7 +1619,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() MEDCouplingFieldDouble *f3=(*f1)+(*f2); f3->checkCoherency(); CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); double values1[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; const double *tmp=f3->getArray()->getConstPointer(); std::transform(tmp,tmp+9,values1,values1,std::minus()); @@ -1626,7 +1631,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() f3=(*f1)*(*f2); f3->checkCoherency(); CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); double values2[9]={0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96}; tmp=f3->getArray()->getConstPointer(); std::transform(tmp,tmp+9,values2,values2,std::minus()); @@ -1639,7 +1644,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() MEDCouplingFieldDouble *f4=(*f1)-(*f3); f4->checkCoherency(); CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); double values3[9]={0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4}; tmp=f4->getArray()->getConstPointer(); std::transform(tmp,tmp+9,values3,values3,std::minus()); @@ -1653,23 +1658,23 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() f4=(*f3)/(*f2); f4->checkCoherency(); CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); tmp=f4->getArray()->getConstPointer(); for(int i=0;i<9;i++) CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,tmp[i],1.e-12); f3->decrRef(); f4->decrRef(); // - f4=f2->buildNewTimeReprFromThis(ONE_TIME,false); + f4=f2->buildNewTimeReprFromThis(NO_TIME,false); f4->checkCoherency(); CPPUNIT_ASSERT(f4->getArray()==f2->getArray()); CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(NO_TIME,false); + MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(ONE_TIME,false); CPPUNIT_ASSERT(f4->getArray()==f5->getArray()); CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); f3=(*f1)+(*f5); tmp=f3->getArray()->getConstPointer(); double values4[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; @@ -1681,17 +1686,17 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() f4->decrRef(); f3->decrRef(); // - f4=f2->buildNewTimeReprFromThis(ONE_TIME,true); + f4=f2->buildNewTimeReprFromThis(NO_TIME,true); f4->checkCoherency(); CPPUNIT_ASSERT(f4->getArray()!=f2->getArray()); CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - f5=f4->buildNewTimeReprFromThis(NO_TIME,true); + f5=f4->buildNewTimeReprFromThis(ONE_TIME,true); CPPUNIT_ASSERT(f4->getArray()!=f5->getArray()); CPPUNIT_ASSERT(f2->getArray()!=f5->getArray()); CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); f3=(*f1)+(*f5); tmp=f3->getArray()->getConstPointer(); double values5[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; @@ -1711,12 +1716,14 @@ void MEDCouplingBasicsTest1::testOperationsOnFields() void MEDCouplingBasicsTest1::testOperationsOnFields2() { MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + m->setTime(3.4,5,6); m->setTimeUnit("us"); + int a,b; MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); MEDCouplingFieldDouble *f3=(*f1)/(*f2); f3->checkCoherency(); CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, 0.7407407407407407, 1.129032258064516, 0.81632653061224492, 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; @@ -1730,6 +1737,9 @@ void MEDCouplingBasicsTest1::testOperationsOnFields2() f2->decrRef(); // f1=m->buildOrthogonalField(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); f2=m->fillFromAnalytic(ON_CELLS,1,"x"); f3=(*f1)*(*f2); const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; @@ -1758,7 +1768,7 @@ void MEDCouplingBasicsTest1::testOperationsOnFields3() (*f1)/=(*f2); f1->checkCoherency(); CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, 0.7407407407407407, 1.129032258064516, 0.81632653061224492, 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index f6953bbd8..cfc4f7ec6 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -1989,7 +1989,12 @@ void MEDCouplingBasicsTest2::testGetNodeIdsOfCell1() void MEDCouplingBasicsTest2::testGetEdgeRatioField1() { MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; MEDCouplingFieldDouble *f1=m1->getEdgeRatioField(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx index fcc86c4ac..230547686 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx @@ -1256,24 +1256,26 @@ void MEDCouplingBasicsTest3::testGetNodeIdsNearPoints1() mesh->setCoords(tmp2); tmp2->decrRef(); const double pts[6]={0.2,0.2,0.1,0.3,-0.3,0.7}; - std::vector c=mesh->getNodeIdsNearPoint(pts,1e-7); - CPPUNIT_ASSERT_EQUAL(3,(int)c.size()); - CPPUNIT_ASSERT_EQUAL(4,c[0]); - CPPUNIT_ASSERT_EQUAL(9,c[1]); - CPPUNIT_ASSERT_EQUAL(11,c[2]); - c.clear(); - std::vector cI; + DataArrayInt *c=mesh->getNodeIdsNearPoint(pts,1e-7); + CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); + c->decrRef(); + DataArrayInt *cI=0; mesh->getNodeIdsNearPoints(pts,3,1e-7,c,cI); - CPPUNIT_ASSERT_EQUAL(4,(int)cI.size()); - CPPUNIT_ASSERT_EQUAL(4,(int)c.size()); - CPPUNIT_ASSERT_EQUAL(4,c[0]); - CPPUNIT_ASSERT_EQUAL(9,c[1]); - CPPUNIT_ASSERT_EQUAL(11,c[2]); - CPPUNIT_ASSERT_EQUAL(6,c[3]); - CPPUNIT_ASSERT_EQUAL(0,cI[0]); - CPPUNIT_ASSERT_EQUAL(3,cI[1]); - CPPUNIT_ASSERT_EQUAL(3,cI[2]); - CPPUNIT_ASSERT_EQUAL(4,cI[3]); + CPPUNIT_ASSERT_EQUAL(4,cI->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); + CPPUNIT_ASSERT_EQUAL(6,c->getIJ(3,0)); + CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(2,0)); + CPPUNIT_ASSERT_EQUAL(4,cI->getIJ(3,0)); + c->decrRef(); + cI->decrRef(); mesh->decrRef(); } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index e422be808..a802556ad 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -398,11 +398,16 @@ void MEDCouplingBasicsTest4::testApplyFuncThree1() void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1() { MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic2(ON_NODES,1,"y+z"),INTERP_KERNEL::Exception); m1->getCoords()->setInfoOnComponent(0,"x [m]"); m1->getCoords()->setInfoOnComponent(1,"y"); m1->getCoords()->setInfoOnComponent(2,"z"); MEDCouplingFieldDouble *f1=m1->fillFromAnalytic2(ON_NODES,1,"y+z"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; @@ -415,11 +420,16 @@ void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1() void MEDCouplingBasicsTest4::testFillFromAnalyticThree1() { MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; std::vector vs(3); vs[0]="x"; vs[1]="Y"; vs[2]="z"; CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"),INTERP_KERNEL::Exception); vs[1]="y"; MEDCouplingFieldDouble *f1=m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; @@ -1589,11 +1599,11 @@ void MEDCouplingBasicsTest4::testFindAndCorrectBadOriented3DExtrudedCells1() m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+48); m->finishInsertingCells(); // - std::vector v; - m->findAndCorrectBadOriented3DExtrudedCells(v); - CPPUNIT_ASSERT_EQUAL(4,(int)v.size()); - CPPUNIT_ASSERT(std::equal(v.begin(),v.end(),invalidCells)); + DataArrayInt *v=m->findAndCorrectBadOriented3DExtrudedCells(); + CPPUNIT_ASSERT_EQUAL(4,v->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(v->begin(),v->end(),invalidCells)); CPPUNIT_ASSERT(std::equal(connExp,connExp+64,m->getNodalConnectivity()->getConstPointer())); + v->decrRef(); // m->decrRef(); } @@ -1650,9 +1660,9 @@ void MEDCouplingBasicsTest4::testNonRegressionCopyTinyStrings() MEDCouplingFieldDouble *f1=m->getMeasureField(true); f1->getArray()->setInfoOnComponent(0,"P [N/m^2]"); DataArrayDouble *bary=m->getBarycenterAndOwner(); - MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(ONE_TIME,false); + MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(NO_TIME,false); f2->setArray(bary); - CPPUNIT_ASSERT_THROW(f2->copyTinyAttrFrom(f1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(f1->copyTinyAttrFrom(f2),INTERP_KERNEL::Exception); m->decrRef(); f1->decrRef(); bary->decrRef(); @@ -1892,12 +1902,13 @@ void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() b->alloc(3,1); std::copy(arrI,arrI+3,b->getPointer()); int newNbTuple=-1; - DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a,b,newNbTuple); + DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple); const int expected[10]={0,1,2,0,3,4,5,4,6,4}; CPPUNIT_ASSERT_EQUAL(10,ret->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(7,newNbTuple); CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); + CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception); ret->decrRef(); b->decrRef(); a->decrRef(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx index 9e98601c0..7b1c4392d 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -1672,3 +1672,306 @@ void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1() CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin())); e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef(); } + +void MEDCouplingBasicsTest5::testDAICheckMonotonic1() +{ + const int data1[6]={-1,0,2,2,4,5}; + const int data2[6]={6,2,0,-8,-9,-56}; + const int data3[6]={-1,0,3,2,4,6}; + const int data4[6]={7,5,2,3,0,-6}; + DataArrayInt *d=DataArrayInt::New(); + d->useArray(data1,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(d->isMonotonic(true)); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + d->checkMonotonic(true); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data2,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + d->checkMonotonic(false); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + d->useArray(data3,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data4,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data4,false,CPP_DEALLOC,0,1); + CPPUNIT_ASSERT(d->isMonotonic(true)); + CPPUNIT_ASSERT(d->isMonotonic(false)); + d->checkMonotonic(true); + d->checkMonotonic(false); + d->useArray(data4,false,CPP_DEALLOC,3,2);//throw because nbComp!=1 + CPPUNIT_ASSERT_THROW(d->isMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->isMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->decrRef(); +} + +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6() +{ + // coordinates + DataArrayDouble *coords=DataArrayDouble::New(); + const double coordsData[16]={2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15}; + coords->useArray(coordsData,false,CPP_DEALLOC,8,2); + // connectivity + DataArrayInt *conn=DataArrayInt::New(); + const int connData[9]={8,0,3,5,1,4,6,7,2}; + conn->useArray(connData,false,CPP_DEALLOC,9,1); + DataArrayInt *connI=DataArrayInt::New(); + const int connIData[2]={0,9}; + connI->useArray(connIData,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fixe",2); + m1->setCoords(coords); + m1->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + coords=DataArrayDouble::New(); + const double coordsData2[26]={-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839}; + coords->useArray(coordsData2,false,CPP_DEALLOC,13,2); + // connectivity + conn=DataArrayInt::New(); + const int connData2[18]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12}; + conn->useArray(connData2,false,CPP_DEALLOC,18,1); + connI=DataArrayInt::New(); + const int connIData2[3]={0,9,18}; + connI->useArray(connIData2,false,CPP_DEALLOC,3,1); + // + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); + m2->setCoords(coords); + m2->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); + CPPUNIT_ASSERT_EQUAL(4,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(43,m3->getNumberOfNodes()); + bool areMerged=false; + int newNbOfNodes=-1; + m3->mergeNodes(1e-12,areMerged,newNbOfNodes)->decrRef(); + CPPUNIT_ASSERT_EQUAL(35,m3->getNumberOfNodes()); + m3->zipCoords(); + CPPUNIT_ASSERT_EQUAL(23,m3->getNumberOfNodes()); + // + MEDCouplingFieldDouble *f=m3->getMeasureField(true); + const double *vals=f->getArray()->getConstPointer(); + const double valuesExpected[4]={1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i],vals[i],1e-12); + f->decrRef(); + // + m1->decrRef(); + m2->decrRef(); + m3->decrRef(); + d1->decrRef(); + d2->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1() +{ + const int tab1[7]={1,3,5,6,7,9,13}; + const int tab2[3]={3,5,9}; + const int tab3[3]={1,3,5}; + DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); + DataArrayInt *da2=DataArrayInt::New(); da2->useArray(tab2,false,CPP_DEALLOC,3,1); + DataArrayInt *da3=DataArrayInt::New(); da3->useArray(tab3,false,CPP_DEALLOC,3,1); + DataArrayInt *da4=DataArrayInt::New(); da4->useArray(tab1,false,CPP_DEALLOC,7,1); + // + DataArrayInt *a=0; + a=da1->buildSubstractionOptimized(da2); + CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + const int expected1_0[4]={1,6,7,13}; + CPPUNIT_ASSERT(std::equal(expected1_0,expected1_0+4,a->begin())); + a->decrRef(); + // + a=da1->buildSubstractionOptimized(da3); + CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + const int expected2_0[4]={6,7,9,13}; + CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+4,a->begin())); + a->decrRef(); + // + a=da1->buildSubstractionOptimized(da4); + CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + a->decrRef(); + // + da1->decrRef(); + da2->decrRef(); + da3->decrRef(); + da4->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIIsStrictlyMonotonic1() +{ + const int tab1[7]={1,3,5,6,7,9,13}; + DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + int tab2[7]={1,3,5,6,6,9,13}; + da1=DataArrayInt::New(); da1->useArray(tab2,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + const int tab3[7]={1,3,5,6,5,9,13}; + da1=DataArrayInt::New(); da1->useArray(tab3,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + const int tab4[7]={13,9,7,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab4,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + const int tab5[7]={13,9,6,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab5,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + const int tab6[7]={13,9,5,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab6,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,0,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,1,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); +} + +void MEDCouplingBasicsTest5::testSimplexize3() +{ + const int conn[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("toto",3); + m->allocateCells(0); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+0); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+12); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+20); + const double coords[72]={0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.,2.,0.,0.,2.,1.,0.,3.,1.,0.,3.,0.,0.,2.,0.,1.,2.,1.,1.,3.,1.,1.,3.,0.,1.,4.,0.,0.,4.,1.,0.,5.,1.,0.,5.,0.,0.,4.,0.,1.,4.,1.,1.,5.,1.,1.,5.,0.,1.,6.,0.,0.,6.,1.,0.,7.,0.,0.,6.,0.,1.}; + DataArrayDouble *c=DataArrayDouble::New(); + c->useArray(coords,false,CPP_DEALLOC,24,3); + m->setCoords(c); + c->decrRef(); + m->checkCoherency2(); + // + MEDCouplingUMesh *m1=static_cast(m->deepCpy()); + DataArrayInt *d1=m1->simplexize(INTERP_KERNEL::PLANAR_FACE_5); + m1->checkCoherency2(); + MEDCouplingFieldDouble *f1=m1->getMeasureField(ON_CELLS); + const double vol1Expected[12]={1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6}; + CPPUNIT_ASSERT_EQUAL(1,f1->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,f1->getArray()->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1Expected[i],f1->getIJ(i,0),1e-12); + const int connExpected1[60]={14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23}; + const int connIExpected1[13]={0,5,10,15,20,25,30,35,40,45,50,55,60}; + const int n2o1[12]={0,1,1,1,1,1,2,2,2,2,2,3}; + CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivity()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(60,m1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivityIndex()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(13,m1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExpected1,connExpected1+60,m1->getNodalConnectivity()->begin())); + CPPUNIT_ASSERT(std::equal(connIExpected1,connIExpected1+13,m1->getNodalConnectivityIndex()->begin())); + CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(n2o1,n2o1+12,d1->begin())); + f1->decrRef(); + m1->decrRef(); + d1->decrRef(); + // + MEDCouplingUMesh *m2=static_cast(m->deepCpy()); + DataArrayInt *d2=m2->simplexize(INTERP_KERNEL::PLANAR_FACE_6); + m2->checkCoherency2(); + MEDCouplingFieldDouble *f2=m2->getMeasureField(ON_CELLS); + const double vol2Expected[14]={1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6}; + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(14,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol2Expected[i],f2->getIJ(i,0),1e-12); + const int connExpected2[70]={14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23}; + const int connIExpected2[15]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70}; + const int n2o2[14]={0,1,1,1,1,1,1,2,2,2,2,2,2,3}; + CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivity()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(70,m2->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivityIndex()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(15,m2->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExpected2,connExpected2+70,m2->getNodalConnectivity()->begin())); + CPPUNIT_ASSERT(std::equal(connIExpected2,connIExpected2+15,m2->getNodalConnectivityIndex()->begin())); + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(14,d2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(n2o2,n2o2+14,d2->begin())); + f2->decrRef(); + m2->decrRef(); + d2->decrRef(); + // + m->decrRef(); +} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx index 1ee856333..92e1ad52e 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx @@ -69,6 +69,11 @@ namespace ParaMEDMEM CPPUNIT_TEST( testIntersect2DMeshesTmp5 ); CPPUNIT_TEST( testDAIBuildUnique1 ); CPPUNIT_TEST( testDAIPartitionByDifferentValues1 ); + CPPUNIT_TEST( testDAICheckMonotonic1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp6 ); + CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 ); + CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 ); + CPPUNIT_TEST( testSimplexize3 ); CPPUNIT_TEST_SUITE_END(); public: void testUMeshTessellate2D1(); @@ -104,6 +109,11 @@ namespace ParaMEDMEM void testIntersect2DMeshesTmp5(); void testDAIBuildUnique1(); void testDAIPartitionByDifferentValues1(); + void testDAICheckMonotonic1(); + void testIntersect2DMeshesTmp6(); + void testDAIBuildSubstractionOptimized1(); + void testDAIIsStrictlyMonotonic1(); + void testSimplexize3(); }; } diff --git a/src/MEDCouplingCorba/CMakeLists.txt b/src/MEDCouplingCorba/CMakeLists.txt index 07af5fb49..7b0b7bb52 100644 --- a/src/MEDCouplingCorba/CMakeLists.txt +++ b/src/MEDCouplingCorba/CMakeLists.txt @@ -38,6 +38,8 @@ SET(medcouplingcorba_SOURCES MEDCouplingMeshServant.cxx MEDCouplingPointSetServant.cxx MEDCouplingExtrudedMeshServant.cxx + MEDCouplingStructuredMeshServant.cxx + MEDCouplingCurveLinearMeshServant.cxx MEDCouplingCMeshServant.cxx MEDCouplingUMeshServant.cxx MEDCouplingFieldServant.cxx diff --git a/src/MEDCouplingCorba/Client/CMakeLists.txt b/src/MEDCouplingCorba/Client/CMakeLists.txt index c7486da92..912daa5f0 100644 --- a/src/MEDCouplingCorba/Client/CMakeLists.txt +++ b/src/MEDCouplingCorba/Client/CMakeLists.txt @@ -31,6 +31,7 @@ SET(medcouplingclient_SOURCES DataArrayDoubleClient.cxx DataArrayIntClient.cxx MEDCouplingCMeshClient.cxx + MEDCouplingCurveLinearMeshClient.cxx MEDCouplingExtrudedMeshClient.cxx MEDCouplingFieldDoubleClient.cxx MEDCouplingFieldOverTimeClient.cxx diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index bc59a44de..b4446b1dd 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -372,7 +372,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(NORM_QUAD4,mesh.getAllTypes()[1]); self.assertEqual(1,len(subMesh.getAllTypes())); self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]); - self.assertEqual(name,"PartOf_Toto"); + self.assertEqual(name,"Toto"); self.assertEqual(2,subMesh.getNumberOfCells()); subConn=[4,0,3,4,1,4,7,8,5,4]; subConnIndex=[0,5,10]; @@ -387,7 +387,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(2,len(subMesh.getAllTypes())); self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]); self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]); - self.assertEqual(name,"PartOf_Toto"); + self.assertEqual(name,"Toto"); self.assertEqual(3,subMesh.getNumberOfCells()); subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3] subConnIndex2=[0,5,9,14] @@ -952,7 +952,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): name=f3.getName(); self.assertEqual(name,"MeasureOfMesh_"); self.assertEqual(f3.getTypeOfField(),ON_CELLS); - self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f3.getNumberOfComponents()); self.assertEqual(7,f3.getNumberOfTuples()); values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5] @@ -964,11 +964,14 @@ class MEDCouplingBasicsTest(unittest.TestCase): pass def testFillFromAnalytic(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m.setTime(3.4,5,6); m.setTimeUnit("us"); f1=m.fillFromAnalytic(ON_CELLS,1,"x+y"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(5,f1.getNumberOfTuples()); values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] @@ -981,7 +984,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4] @@ -994,7 +997,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(2,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] @@ -1020,7 +1023,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_CELLS,1,"y+x"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(5,f1.getNumberOfTuples()); values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] @@ -1033,7 +1036,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] @@ -1045,7 +1048,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); tmp=f1.getArray().getValues(); @@ -1058,7 +1061,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(2,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] @@ -1080,12 +1083,12 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(2,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); f1.applyFunc(1,"x+y"); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] @@ -1101,7 +1104,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(2,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); # @@ -1111,7 +1114,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertRaises(InterpKernelException, f2.applyFunc, "a/0"); f2.applyFunc("abs(u)^2.4+2*u"); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(2,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, @@ -1127,7 +1130,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): # f1.applyFunc(1,"x+y"); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] @@ -1147,7 +1150,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f3=f1+f2; f3.checkCoherency(); self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] tmp=f3.getArray().getValues(); self.assertEqual(len(values1),len(tmp)) @@ -1158,7 +1161,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f3=f1*f2; f3.checkCoherency(); self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96] tmp=f3.getArray().getValues(); self.assertEqual(len(values2),len(tmp)) @@ -1170,7 +1173,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f4=f1-f3; f4.checkCoherency(); self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4] tmp=f4.getArray().getValues(); self.assertEqual(len(values3),len(tmp)) @@ -1182,20 +1185,20 @@ class MEDCouplingBasicsTest(unittest.TestCase): f4=f3/f2; f4.checkCoherency(); self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); tmp=f4.getArray().getValues(); for i in xrange(len(tmp)): self.assertTrue(abs(tmp[i]-2.)<1.e-12) pass # - f4=f2.buildNewTimeReprFromThis(ONE_TIME,False); + f4=f2.buildNewTimeReprFromThis(NO_TIME,False); f4.checkCoherency(); self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(NO_TIME,False); + f5=f4.buildNewTimeReprFromThis(ONE_TIME,False); self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),NO_TIME); + self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); f3=f1+f5; tmp=f3.getArray().getValues(); values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] @@ -1204,14 +1207,14 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(abs(tmp[i]-values4[i])<1.e-12) pass # - f4=f2.buildNewTimeReprFromThis(ONE_TIME,True); + f4=f2.buildNewTimeReprFromThis(NO_TIME,True); f4.checkCoherency(); self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(NO_TIME,True); + f5=f4.buildNewTimeReprFromThis(ONE_TIME,True); self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),NO_TIME); + self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); f3=f1+f5; tmp=f3.getArray().getValues(); values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] @@ -1223,12 +1226,13 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testOperationsOnFields2(self): m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m.setTime(3.4,5,6); m.setTimeUnit("us"); f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); f3=f1/f2; f3.checkCoherency(); self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, 0.7407407407407407, 1.129032258064516, 0.81632653061224492, 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] @@ -1239,6 +1243,8 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(abs(expected1[i]-val[i])<1.e-12); # f1=m.buildOrthogonalField(); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) f2=m.fillFromAnalytic(ON_CELLS,1,"x"); f3=f1*f2; expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] @@ -1261,7 +1267,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1/=f2 f1.checkCoherency(); self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, 0.7407407407407407, 1.129032258064516, 0.81632653061224492, 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] @@ -3644,7 +3650,10 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testGetEdgeRatioField1(self): m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); f1=m1.getEdgeRatioField(); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); self.assertEqual(5,f1.getNumberOfTuples()); self.assertEqual(1,f1.getNumberOfComponents()); @@ -5508,6 +5517,10 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(pt[1],tmp.getIJ(0,1)); ret,tmp=m2.areCellsIncludedIn(m,0) self.assertTrue(not ret); + m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2) + c,cI=m3.findCommonCells(2,m.getNumberOfCells()) + self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6]))) + self.assertTrue(cI.isEqual(DataArrayInt([0,2,4]))) pass def testSwigErrorProtection1(self): @@ -5721,31 +5734,31 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testSwigErrorProtection3(self): da=DataArrayInt.New() - da.setValues([1,2,3,4],4,3) + da.setValues([1,2,3,4,0,0,0,0,0,0,0,0],4,3) self.assertEqual([1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); da=DataArrayInt.New() - da.setValues((1,2,3,4,4,3),4,3) + da.setValues(((1,2,3),(4,4,3),(0,0,0),(0,0,0)),4,3) self.assertEqual([1, 2, 3, 4, 4, 3, 0, 0, 0, 0, 0, 0],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); - da.setValues(10*[1]+290*[2],4,3) + da.setValues((10*[1]+290*[2])[:12],4,3) self.assertEqual(10*[1]+[2,2],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); # da=DataArrayDouble.New() - da.setValues([1,2,3.,4],4,3) + da.setValues([1,2,3.,4,0,0,0,0,0,0,0,0],4,3) self.assertEqual([1., 2., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0.],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); da=DataArrayDouble.New() - da.setValues((1,2,3,4.,4,3),4,3) + da.setValues(((1,2,3),(4.,4,3),(0,0,0),(0,0,0)),4,3) self.assertEqual([1., 2., 3., 4., 4., 3., 0., 0., 0., 0., 0., 0.],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); - da.setValues(10*[1]+290*[2],4,3) + da.setValues((10*[1]+290*[2])[:12],4,3) self.assertEqual(10*[1.]+[2.,2.],da.getValues()) self.assertEqual(3,da.getNumberOfComponents()); self.assertEqual(4,da.getNumberOfTuples()); @@ -6907,11 +6920,14 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testFillFromAnalyticTwo1(self): m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); self.assertRaises(InterpKernelException,m1.fillFromAnalytic2,ON_NODES,1,"y+z"); m1.getCoords().setInfoOnComponent(0,"x [m]"); m1.getCoords().setInfoOnComponent(1,"y"); m1.getCoords().setInfoOnComponent(2,"z"); f1=m1.fillFromAnalytic2(ON_NODES,1,"y+z"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] @@ -6922,11 +6938,14 @@ class MEDCouplingBasicsTest(unittest.TestCase): def testFillFromAnalyticThree1(self): m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); vs=3*[None]; vs[0]="x"; vs[1]="Y"; vs[2]="z"; self.assertRaises(InterpKernelException,m1.fillFromAnalytic3,ON_NODES,1,vs,"y+z"); vs[1]="y"; f1=m1.fillFromAnalytic3(ON_NODES,1,vs,"y+z"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) self.assertEqual(1,f1.getNumberOfComponents()); self.assertEqual(9,f1.getNumberOfTuples()); expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] @@ -7904,6 +7923,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(4,len(v)); self.assertEqual(v.getValues(),invalidCells); self.assertEqual(connExp,m.getNodalConnectivity().getValues()); + self.assertTrue(m.findAndCorrectBadOriented3DExtrudedCells().empty()) # pass @@ -7952,9 +7972,9 @@ class MEDCouplingBasicsTest(unittest.TestCase): f1=m.getMeasureField(True) f1.getArray().setInfoOnComponent(0,"P [N/m^2]") bary=m.getBarycenterAndOwner() - f2=f1.buildNewTimeReprFromThis(ONE_TIME,False) + f2=f1.buildNewTimeReprFromThis(NO_TIME,False) f2.setArray(bary) - self.assertRaises(InterpKernelException,f2.copyTinyAttrFrom,f1) + self.assertRaises(InterpKernelException,f1.copyTinyAttrFrom,f2) pass def testDaDSetPartOfValuesAdv1(self): @@ -8128,6 +8148,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(7,newNbTuple); self.assertEqual(1,ret.getNumberOfComponents()); self.assertEqual(expected,ret.getValues()); + self.assertRaises(InterpKernelException,DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2,9,a,b); pass def testDADIReverse1(self): @@ -8152,7 +8173,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): for i in xrange(6): self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14); pass - b.setValues(arr2,5,1); + b.setValues(arr2[:5],5,1); self.assertAlmostEqual(9.,b.back(),14) b.reverse(); for i in xrange(5): @@ -10397,6 +10418,701 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12) pass + def testDAICheckMonotonic1(self): + data1=[-1,0,2,2,4,5] + data2=[6,2,0,-8,-9,-56] + data3=[-1,0,3,2,4,6] + data4=[7,5,2,3,0,-6] + d=DataArrayInt.New(data1); + self.assertTrue(d.isMonotonic(True)); + self.assertTrue(not d.isMonotonic(False)); + d.checkMonotonic(True); + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(data2); + self.assertTrue(d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + d.checkMonotonic(False); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + d=DataArrayInt.New(data3); + self.assertTrue(not d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(data4); + self.assertTrue(not d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(0,1) + self.assertTrue(d.isMonotonic(True)); + self.assertTrue(d.isMonotonic(False)); + d.checkMonotonic(True); + d.checkMonotonic(False); + d=DataArrayInt.New(data4,3,2);#throw because nbComp!=1 + self.assertRaises(InterpKernelException,d.isMonotonic,True) + self.assertRaises(InterpKernelException,d.isMonotonic,False) + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + pass + + def testSwigDASetItemOnEmpty1(self): + d=DataArrayInt(0,1) + isThrow=False + try: + d[0:1000:2]=4 + except InterpKernelException as e: + isThrow=True + pass + self.assertTrue(isThrow) + d[:]=4 + d[::2]=5 + # + d=DataArrayDouble(0,1) + isThrow=False + try: + d[0:1000:2]=4 + except InterpKernelException as e: + isThrow=True + pass + self.assertTrue(isThrow) + d[:]=4 + d[::2]=5 + d=DataArrayInt([],0,1) + d2=DataArrayInt(0) + self.assertTrue(d2.isEqual(d)) + d=DataArrayDouble([],0,1) + d2=DataArrayDouble(0) + self.assertTrue(d2.isEqual(d,1e-12)) + pass + + def testSwigDAITransformWithIndArr1(self): + arr=DataArrayInt([0,4,5,1]) + d=DataArrayInt([7,8,9,10]) + self.assertRaises(InterpKernelException,arr.transformWithIndArr,d) + pass + + def testIntersect2DMeshesTmp6(self): + # coordinates + coords=DataArrayDouble.New([2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15],8,2); + # connectivity + conn=DataArrayInt.New([8,0,3,5,1,4,6,7,2]) + connI=DataArrayInt.New([0,9]); + m1=MEDCouplingUMesh.New("Fixe",2); + m1.setCoords(coords); + m1.setConnectivity(conn,connI,True); + # + coords=DataArrayDouble.New([-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839],13,2); + # connectivity + conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12]); + connI=DataArrayInt.New([0,9,18]); + # + m2=MEDCouplingUMesh.New("Mobile",2); + m2.setCoords(coords); + m2.setConnectivity(conn,connI,True); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); + self.assertTrue(d1.isEqual(DataArrayInt([0,0,0,0]))); + self.assertTrue(d2.isEqual(DataArrayInt([0,1,-1,-1]))); + self.assertEqual(4,m3.getNumberOfCells()); + self.assertEqual(4,d1.getNumberOfTuples()); + self.assertEqual(4,d2.getNumberOfTuples()); + self.assertEqual(43,m3.getNumberOfNodes()); + dI,areMerged,newNbOfNodes=m3.mergeNodes(1e-12) + self.assertEqual(35,m3.getNumberOfNodes()); + m3.zipCoords(); + self.assertEqual(23,m3.getNumberOfNodes()); + # + f=m3.getMeasureField(True); + valuesExpected=DataArrayDouble([1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694]) + self.assertTrue(f.getArray().isEqual(valuesExpected,1e-12)) + pass + + def testDAPushBack(self): + d=DataArrayDouble(0,1) + for i in xrange(8): + d.pushBackSilent(i) + pass + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),8) + d.pushBackSilent(4.44) + self.assertEqual(d.getNumberOfTuples(),9) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) + e=d.deepCpy() + self.assertEqual(e.getNumberOfTuples(),9) + self.assertEqual(e.getNbOfElemAllocated(),9) + self.assertTrue(e.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) + self.assertAlmostEqual(d.popBackSilent(),4.44,12) + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.]),1e-12)) + f=DataArrayDouble() + f.reserve(1000) + f.pushBackSilent(4.) + self.assertTrue(f.isEqual(DataArrayDouble([4.]),1e-12)) + self.assertEqual(f.getNumberOfTuples(),1) + self.assertEqual(f.getNbOfElemAllocated(),1000) + ff=f[:] + self.assertTrue(ff.isEqual(DataArrayDouble([4.]),1e-12)) + self.assertEqual(ff.getNumberOfTuples(),1) + self.assertEqual(ff.getNbOfElemAllocated(),1) + d=DataArrayDouble() + d.pushBackSilent(4.44) + d.pushBackSilent(5.55) + d.pushBackSilent(6.66) + self.assertTrue(d.isEqual(DataArrayDouble([4.44,5.55,6.66]),1e-12)) + # + d=DataArrayInt(0,1) + for i in xrange(8): + d.pushBackSilent(i) + pass + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),8) + d.pushBackSilent(444) + self.assertEqual(d.getNumberOfTuples(),9) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) + e=d.deepCpy() + self.assertEqual(e.getNumberOfTuples(),9) + self.assertEqual(e.getNbOfElemAllocated(),9) + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) + self.assertEqual(d.popBackSilent(),444) + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) + f=DataArrayInt() + f.reserve(1000) + f.pushBackSilent(4) + self.assertTrue(f.isEqual(DataArrayInt([4]))) + self.assertEqual(f.getNumberOfTuples(),1) + self.assertEqual(f.getNbOfElemAllocated(),1000) + ff=f[:] + self.assertTrue(ff.isEqual(DataArrayInt([4]))) + self.assertEqual(ff.getNumberOfTuples(),1) + self.assertEqual(ff.getNbOfElemAllocated(),1) + d=DataArrayInt() + d.pushBackSilent(444) + d.pushBackSilent(555) + d.pushBackSilent(666) + self.assertTrue(d.isEqual(DataArrayInt([444,555,666]))) + # + d=DataArrayInt() + d.alloc(10,1) + d.setInfoOnComponent(0,"ABC") + d.setName("dEf") + d.iota(7) + e=DataArrayInt([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(10,d.getNbOfElemAllocated()) + d.pushBackSilent(55) + e=DataArrayInt([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(20,d.getNbOfElemAllocated()) + d.reserve(4) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(4,d.getNbOfElemAllocated()) + d.pushBackSilent(5) + e=DataArrayInt([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertEqual(5,d.popBackSilent()) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertRaises(InterpKernelException,d.reserve,-1) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + d.reserve(0) + e=DataArrayInt([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e)) + self.assertEqual(0,d.getNbOfElemAllocated()) + # + d=DataArrayDouble() + d.alloc(10,1) + d.setInfoOnComponent(0,"ABC") + d.setName("dEf") + d.iota(7) + e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(10,d.getNbOfElemAllocated()) + d.pushBackSilent(55) + e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(20,d.getNbOfElemAllocated()) + d.reserve(4) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(4,d.getNbOfElemAllocated()) + d.pushBackSilent(5) + e=DataArrayDouble([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertEqual(5.,d.popBackSilent()) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertRaises(InterpKernelException,d.reserve,-1) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + d.reserve(0) + e=DataArrayDouble([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(0,d.getNbOfElemAllocated()) + pass + + def testDAIBuildSubstractionOptimized1(self): + da1=DataArrayInt.New([1,3,5,6,7,9,13]) + da2=DataArrayInt.New([3,5,9]) + da3=DataArrayInt.New([1,3,5]) + da4=DataArrayInt.New([1,3,5,6,7,9,13]) + # + a=da1.buildSubstractionOptimized(da2); + self.assertTrue(a.isEqual(DataArrayInt([1,6,7,13]))); + # + a=da1.buildSubstractionOptimized(da3); + self.assertTrue(a.isEqual(DataArrayInt([6,7,9,13]))); + # + a=da1.buildSubstractionOptimized(da4); + self.assertTrue(a.isEqual(DataArrayInt([]))); + pass + + def testDAIIsStrictlyMonotonic1(self): + da1=DataArrayInt.New([1,3,5,6,7,9,13]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([1,3,5,6,6,9,13]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([1,3,5,6,5,9,13]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([13,9,7,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13,9,6,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13,9,5,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + pass + + def testFindAndCorrectBadOriented3DCells1(self): + nbOfDisc=20 + vects=([0,0,-1],[0.3,0.7,0.2],[-0.3,0.7,0.2],[-0.3,-0.7,0.2]) + # + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0) + self.assertRaises(InterpKernelException,m4.insertNextCell,NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11,12]); + m4.insertNextCell(NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11]); #Well oriented + c0=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) ; m0.setCoords(c0) + c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.],5,3) ; m1.setCoords(c1) + c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,0.,1.],6,3) ; m2.setCoords(c2) + c3=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; m3.setCoords(c3) + c4=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.8,0.,0.,0.45,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.,0.8,0.,1.,0.45,0.,1.],12,3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected1=DataArrayDouble([0.16666666666666666,0.3333333333333333,0.5,1.,1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().empty()) + self.assertTrue(mm.isEqual(mm2,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + # + mOK=m.deepCpy() + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,2,1,3]); #Not well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,3,2,1,4,7,6,5]); #Not well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,[0,5,4,3,2,1,6,11,10,9,8,7]); #Not well oriented + m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected2=DataArrayDouble([-0.16666666666666666,0.3333333333333333,0.5,-1.,-1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() + self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected2,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected2,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([0,3,4]))) + mOK.setCoords(mm.getCoords()) + self.assertTrue(mm.isEqual(mOK,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mmm=mm.deepCpy() + self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + # + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,3,2,1,4]); #Not well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,2,1,3,5,4]); #Not well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,range(12)); #Well oriented + m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected3=DataArrayDouble([0.16666666666666666,-0.3333333333333333,-0.5,1.,1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() + self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected3,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected3,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([1,2]))) + mOK.setCoords(mm.getCoords()) + self.assertTrue(mm.isEqual(mOK,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mmm=mm.deepCpy() + self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + pass + + def testSwigCellOrientation1(self): + coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3) + conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]] + for i in xrange(256): + mesh=MEDCouplingUMesh("FluidMesh_1",3); + mesh.allocateCells(0) + conn2=[elt[:] for elt in conn] + code=bin(i)[2:] ; code='0'*(8-len(code))+code + for face,rev in zip(conn2,code): + if bool(int(rev)): + face.reverse() + pass + pass + conn3=[elt+[-1] for elt in conn2] + conn3=sum(conn3,[])[:-1] + mesh.insertNextCell(NORM_POLYHED,conn3) + mesh.setCoords(coords) + mesh.orientCorrectlyPolyhedrons() + self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12)) + pass + pass + + def testSwigCheckConsecutiveCellTypesForMEDFileFrmt1(self): + m1=MEDCouplingUMesh("",2) ; m1.allocateCells(0) + m1.insertNextCell(NORM_QUAD4,[0,1,2,3]) + m1.insertNextCell(NORM_TRI3,[0,1,2]) + d=DataArrayDouble(4,3) ; d[:]=0. + m1.setCoords(d) + self.assertTrue(m1.checkConsecutiveCellTypes()) + self.assertTrue(not m1.checkConsecutiveCellTypesForMEDFileFrmt()) + m1.renumberCells([1,0]) + self.assertTrue(m1.checkConsecutiveCellTypes()) + self.assertTrue(m1.checkConsecutiveCellTypesForMEDFileFrmt()) + pass + + def testSwigDAAccumulate1(self): + d=DataArrayInt(10) ; d.iota(0) + self.assertEqual([45],d.accumulate()) + self.assertEqual(45,d.accumulate(0)) + d=DataArrayInt(30) ; d.iota(0) ; d.rearrange(3) + self.assertEqual([135,145,155],d.accumulate()) + self.assertEqual(135,d.accumulate(0)) + self.assertEqual(145,d.accumulate(1)) + self.assertEqual(155,d.accumulate(2)) + d=DataArrayDouble(10) ; d.iota(0.) + self.assertEqual([45.],d.accumulate()) + self.assertEqual(45.,d.accumulate(0)) + d=DataArrayDouble(30) ; d.iota(0) ; d.rearrange(3) + self.assertEqual([135.,145.,155.],d.accumulate()) + self.assertEqual(135.,d.accumulate(0)) + self.assertEqual(145.,d.accumulate(1)) + self.assertEqual(155.,d.accumulate(2)) + pass + + def testSwigUMeshDistanceToMesh1(self): + m=MEDCouplingUMesh("toto",2) + coords=DataArrayDouble([2.3,3.4,5.6,6.5,-4.3,3.2,-9.8,7.6,-5.4],3,3) + m.setCoords(coords) + m.allocateCells(0) + m.insertNextCell(NORM_TRI3,[0,1,2]) + a,b,c=m.distanceToPoint([-0.335,2.27,1.21]) + self.assertEqual(0,b) ; self.assertEqual(0,c) + self.assertAlmostEqual(0.022360988100374124,a,14); + a,b,c=m.distanceToPoint(DataArrayDouble([-0.335,2.27,1.21],1,3)) + self.assertEqual(0,b) ; self.assertEqual(0,c) + self.assertAlmostEqual(0.022360988100374124,a,14); + a,b=coords.distanceToTuple([-0.335,2.27,1.21]) + self.assertAlmostEqual(5.243302871282566,a,14) + self.assertEqual(0,b) + # + m=MEDCouplingUMesh("toto",2) + coords=DataArrayDouble([0.,0.,0., 8.,0.,0., 8.,8.,0., 0.,8.,0.],4,3) + m.setCoords(coords) + m.allocateCells(0) + m.insertNextCell(NORM_QUAD4,[0,1,2,3]) + m.checkCoherency2() + self.assertEqual([4,0,1,2,3],m.getNodalConnectivity().getValues()) + a,b,c=m.distanceToPoint([5.,2.,0.1]) + self.assertAlmostEqual(0.1,a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c) + a,b,c=m.distanceToPoint([5.,-2.,4.]) + self.assertAlmostEqual(sqrt(2*2+4*4),a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c) + m.allocateCells(0) + m.insertNextCell(NORM_POLYGON,[0,1,2,3]) + m.checkCoherency2() + self.assertEqual([5,0,1,2,3],m.getNodalConnectivity().getValues()) + a,b,c=m.distanceToPoint([11.,3.,4.]) + self.assertAlmostEqual(sqrt(3*3+4*4),a,14) ; self.assertEqual(0,b) ; self.assertEqual(1,c) + a,b,c=m.distanceToPoint([4.,12.,5.]) + self.assertAlmostEqual(sqrt(4*4+5*5),a,14) ; self.assertEqual(0,b) ; self.assertEqual(2,c) + d=DataArrayDouble([-1.2,3.,2.],1,3) + for elt in d: + a,b,c=m.distanceToPoint(d) + self.assertAlmostEqual(sqrt(1.2*1.2+2*2),a,14) ; self.assertEqual(0,b) ; self.assertEqual(0,c) + pass + # + m=MEDCouplingUMesh("toto",1) + coords=DataArrayDouble([0.,0.,4.,0.,0.,4.],3,2) ; m.setCoords(coords) + m.allocateCells(0) ; m.insertNextCell(NORM_SEG2,[0,1]) ; m.insertNextCell(NORM_SEG2,[1,2]) + a,b,c=m.distanceToPoint([-0.1,4.1]) + self.assertAlmostEqual(0.14142135623730925,a,14) ; self.assertEqual(-1,b) ; self.assertEqual(2,c) + a,b,c=m.distanceToPoint([0.,3.9]) + self.assertAlmostEqual(0.07071067811865482,a,14) ; self.assertEqual(1,b) ; self.assertEqual(2,c) + pass + + def testSwigNonRegressionPartitionBySpreadZone1(self): + m=MEDCouplingCMesh() + arr=DataArrayDouble(6) ; arr.iota(0.) + m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + mPart=m[50,80,85,87,92,122] + zones=mPart.partitionBySpreadZone() + self.assertEqual(4,len(zones)) + self.assertTrue(zones[0].isEqual(DataArrayInt([0]))) + self.assertTrue(zones[1].isEqual(DataArrayInt([1,2]))) + self.assertTrue(zones[2].isEqual(DataArrayInt([3,4]))) + self.assertTrue(zones[3].isEqual(DataArrayInt([5]))) + # + n,ni=m.computeNeighborsOfCells() + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(0,n,ni) + self.assertEqual(13,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed([1],n,ni) + self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed((2,),n,ni) + self.assertEqual(11,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(DataArrayInt([3]),n,ni) + self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + pass + + def testSwigUMeshInsertNextCell1(self): + m=MEDCouplingUMesh("toto",2) + # + coords=DataArrayDouble([0.,0.,1.,1.,1.,0.]) ; m.setCoords(coords) + da=DataArrayInt([0,1,2]) + m.allocateCells(0) + for i in xrange(5): + m.insertNextCell(NORM_TRI3,da) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + # + da=DataArrayInt([0,1,2,3]) + m.allocateCells(0) + for i in xrange(5): + m.insertNextCell(NORM_TRI3,3,da) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + # + da=DataArrayInt([0,1]) + m.allocateCells(0) + self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,3,da) + # + da=DataArrayInt([0,1,2,0,1,3,0,1,4,0,1,5,0,1,6],5,3) + m.allocateCells(0) + for t in da: + m.insertNextCell(NORM_TRI3,t) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,3,3,0,1,4,3,0,1,5,3,0,1,6]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,None) + pass + + def testSwigCurveLinearMesh1(self): + m=MEDCouplingCurveLinearMesh("toto") + m.setNodeGridStructure([2,3]) + coords=DataArrayDouble([0.,0., 2.,0., 0.,1., 1.9,1.1, 0.3,1.9, 2.2,2.1],6,2) + m.setCoords(coords) + m.checkCoherency() + m0=m.deepCpy() + self.assertTrue(m0.isEqual(m,1e-12)) + m.getCoords().setInfoOnComponents(["X [m]","Y [m]"]) + self.assertTrue(not m0.isEqual(m,1e-12)) + m0=m.deepCpy() + self.assertTrue(m0.isEqual(m,1e-12)) + self.assertEqual(m.getNodeGridStructure(),(2,3)) + pass + + def testSimplexize3(self): + m=MEDCouplingUMesh("toto",3) + m.allocateCells(0) + m.insertNextCell(NORM_TETRA4,[0,1,2,3]) + m.insertNextCell(NORM_HEXA8,[4,5,6,7,8,9,10,11]) + m.insertNextCell(NORM_HEXA8,[12,13,14,15,16,17,18,19]) + m.insertNextCell(NORM_TETRA4,[20,21,22,23]) + c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) + c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; c2+=[2.,0.,0.] + c3=c2+[2.,0.,0.] + c4=c1+[6.,0.,0.] + c=DataArrayDouble.Aggregate([c1,c2,c3,c4]) + m.setCoords(c) + m.checkCoherency2() + # + m1=m.deepCpy() + d1=m1.simplexize(PLANAR_FACE_5) + m1.checkCoherency2() + vol1=m1.getMeasureField(ON_CELLS).getArray() + self.assertTrue(vol1.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6]),1e-12)) + self.assertEqual(m1.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23]) + self.assertEqual(m1.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60]) + self.assertTrue(d1.isEqual(DataArrayInt([0,1,1,1,1,1,2,2,2,2,2,3]))) + # + m2=m.deepCpy() + d2=m2.simplexize(PLANAR_FACE_6) + m2.checkCoherency2() + vol2=m2.getMeasureField(ON_CELLS).getArray() + self.assertTrue(vol2.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6]),1e-12)) + self.assertEqual(m2.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23]) + self.assertEqual(m2.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70]) + self.assertTrue(d2.isEqual(DataArrayInt([0,1,1,1,1,1,1,2,2,2,2,2,2,3]))) + pass + + def testSwigCurveLinearMesh2(self): + c=MEDCouplingCMesh() + #2D + arr1=DataArrayDouble([0,1,3,7]) + arr2=DataArrayDouble([0,1,1.5]) + c.setCoords(arr1,arr2) + u=c.buildUnstructured() + coo=u.getCoords() + cl=MEDCouplingCurveLinearMesh() + cl.setCoords(coo) + cl.setNodeGridStructure([4,3]) + cl.checkCoherency2() + li1=[1.,2.,4.,0.5,1.,2.] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) + self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) + li1_1=[0.5,0.5,2.,0.5,5.,0.5,0.5,1.25,2.,1.25,5.,1.25] + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) + self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) + #3D + c.setCoords(arr1,arr2,arr2) + u=c.buildUnstructured() + coo=u.getCoords() + cl=MEDCouplingCurveLinearMesh() + cl.setCoords(coo) + cl.setNodeGridStructure([4,3,3]) + cl.checkCoherency2() + li2=[1.,2.,4.,0.5, 1.,2.,0.5,1.,2.,0.25,0.5,1.] + li2_1=[0.5,0.5,0.5,2.,0.5,0.5,5.,0.5,0.5,0.5,1.25,0.5,2.,1.25,0.5,5.,1.25,0.5,0.5,0.5,1.25,2.,0.5,1.25,5.,0.5,1.25,0.5,1.25,1.25,2.,1.25,1.25,5.,1.25,1.25] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) + self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) + self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) + #1D spaceDim 1 + coo=DataArrayDouble(5) ; coo.iota(0.) + coo=coo*coo + cl.setCoords(coo) + cl.setNodeGridStructure([5]) + cl.checkCoherency2() + li3=[1.,3.,5.,7.] + li3_1=[0.5,2.5,6.5,12.5] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) + self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) + self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) + #1D spaceDim 2 + coo=DataArrayDouble.Meld(coo,coo) + cl.setCoords(coo) + cl.checkCoherency2() + li4=[sqrt(2.)*elt for elt in [1.,3.,5.,7.]] + li4_1=[0.5,0.5,2.5,2.5,6.5,6.5,12.5,12.5] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) + self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) + self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) + pass + + def testSwigCurveLinearMeshNonRegression1(self): + coords=DataArrayDouble([0.0, 0.0, 0.10000000149011612, 0.6000000238418579, 0.10000000149011612, 0.30000001192092896, 1.100000023841858, 0.10000000149011612, 0.20000000298023224, 0.10000000149011612, 0.6000000238418579, 0.20000000298023224, 0.699999988079071, 0.6000000238418579, 0.10000000149011612, 1.2000000476837158, 0.6000000238418579, 0.30000001192092896, 0.10000000149011612, 1.100000023841858, 0.30000001192092896, 0.5, 1.100000023841858, 0.20000000298023224, 1.0, 1.2000000476837158, 0.10000000149011612, 0.0, 0.10000000149011612, 0.5, 0.5, 0.10000000149011612, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 0.699999988079071, 0.10000000149011612, 0.6000000238418579, 0.699999988079071, 0.6000000238418579, 0.6000000238418579, 0.5, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 0.10000000149011612, 1.0, 0.6000000238418579, 0.699999988079071, 1.2000000476837158, 0.699999988079071, 0.8999999761581421, 1.0, 0.5, 0.10000000149011612, 0.10000000149011612, 1.2000000476837158, 0.699999988079071, 0.10000000149011612, 1.0, 1.0, 0.10000000149011612, 1.100000023841858, 0.10000000149011612, 0.6000000238418579, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 1.100000023841858, 1.100000023841858, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 1.2000000476837158, 1.0, 0.5, 1.100000023841858, 1.2000000476837158, 1.2000000476837158, 1.100000023841858, 1.0],27,3) + m=MEDCouplingCurveLinearMesh("toto") + m.setCoords(coords) + m.setNodeGridStructure([3,3,3]) + # + vol=m.getMeasureField(False).getArray() + self.assertTrue(vol.isEqual(DataArrayDouble([0.11450000709295281, 0.10583334351579375,0.11149999939029423,0.08866666863113633, 0.1404166805123294,0.1250000135352219,0.1270833433481557,0.13258334288001067]),1e-12)) + self.assertTrue(vol.isEqual(m.buildUnstructured().getMeasureField(False).getArray(),1e-12)) + # + self.assertTrue(m.getBarycenterAndOwner().isEqual(m.buildUnstructured().getBarycenterAndOwner(),1e-12)) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 48c3ec0e3..8f47503cf 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -29,6 +29,7 @@ #include "MEDCouplingUMesh.hxx" #include "MEDCouplingExtrudedMesh.hxx" #include "MEDCouplingCMesh.hxx" +#include "MEDCouplingCurveLinearMesh.hxx" #include "MEDCouplingField.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldTemplate.hxx" @@ -60,6 +61,11 @@ using namespace INTERP_KERNEL; $result=convertMesh($1,$owner); } +%typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh* +{ + $result=convertMesh($1,$owner); +} + %typemap(out) ParaMEDMEM::MEDCouplingFieldDiscretization* { $result=convertFieldDiscretization($1,$owner); @@ -143,6 +149,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; %newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O; %newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N; +%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2OBis; %newobject ParaMEDMEM::DataArrayInt::getIdsEqual; %newobject ParaMEDMEM::DataArrayInt::getIdsNotEqual; %newobject ParaMEDMEM::DataArrayInt::getIdsEqualList; @@ -163,6 +170,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::buildComplement; %newobject ParaMEDMEM::DataArrayInt::buildUnion; %newobject ParaMEDMEM::DataArrayInt::buildSubstraction; +%newobject ParaMEDMEM::DataArrayInt::buildSubstractionOptimized; %newobject ParaMEDMEM::DataArrayInt::buildIntersection; %newobject ParaMEDMEM::DataArrayInt::buildUnique; %newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex; @@ -256,6 +264,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingMesh::buildUnstructured; %newobject ParaMEDMEM::MEDCouplingMesh::MergeMeshes; %newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer; +%newobject ParaMEDMEM::MEDCouplingPointSet::getCellsInBoundingBox; %newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes; %newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; %newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; @@ -278,6 +287,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes; %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords; %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; +%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed; %newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; %newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; %newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt; @@ -294,6 +304,8 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField; %newobject ParaMEDMEM::MEDCouplingUMesh::keepCellIdsByType; %newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords; +%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells; +%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells; %newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary; %newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin; %newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes; @@ -308,6 +320,9 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingCMesh::New; %newobject ParaMEDMEM::MEDCouplingCMesh::clone; %newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::getCoords; %newobject ParaMEDMEM::MEDCouplingMultiFields::New; %newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy; %newobject ParaMEDMEM::MEDCouplingFieldOverTime::New; @@ -373,7 +388,57 @@ namespace INTERP_KERNEL } %include "MEDCouplingTimeLabel.hxx" -%include "MEDCouplingRefCountObject.hxx" + +namespace ParaMEDMEM +{ + typedef enum + { + C_DEALLOC = 2, + CPP_DEALLOC = 3 + } DeallocType; + + typedef enum + { + ON_CELLS = 0, + ON_NODES = 1, + ON_GAUSS_PT = 2, + ON_GAUSS_NE = 3, + ON_NODES_KR = 4 + } TypeOfField; + + typedef enum + { + NO_TIME = 4, + ONE_TIME = 5, + LINEAR_TIME = 6, + CONST_ON_TIME_INTERVAL = 7 + } TypeOfTimeDiscretization; + + const char *MEDCouplingVersionStr(); + int MEDCouplingVersion(); + PyObject *MEDCouplingVersionMajMinRel() + { + int tmp0=0,tmp1=0,tmp2=0; + MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_int(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + class MEDCOUPLING_EXPORT RefCountObject + { + protected: + RefCountObject(); + RefCountObject(const RefCountObject& other); + ~RefCountObject(); + public: + bool decrRef() const; + void incrRef() const; + virtual std::size_t getHeapMemorySize() const; + }; +} namespace ParaMEDMEM { @@ -382,7 +447,8 @@ namespace ParaMEDMEM UNSTRUCTURED = 5, UNSTRUCTURED_DESC = 6, CARTESIAN = 7, - EXTRUDED = 8 + EXTRUDED = 8, + CURVE_LINEAR = 9 } MEDCouplingMeshType; class DataArrayInt; @@ -662,55 +728,44 @@ namespace ParaMEDMEM PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - MEDCouplingMesh *ret=self->buildPart(tmp,((const int *)tmp)+size); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - MEDCouplingMesh *ret=self->buildPart(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - ret->setName(da2->getName().c_str()); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingMesh *ret=self->buildPart(tmp,tmp+szArr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); } - PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - DataArrayInt *arr=0; - MEDCouplingMesh *ret=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - ret=self->buildPartAndReduceNodes(tmp,((const int *)tmp)+size,arr); + PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + DataArrayInt *arr=0; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingMesh *ret=self->buildPartAndReduceNodes(tmp,tmp+szArr,arr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - ret=self->buildPartAndReduceNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),arr); - ret->setName(da2->getName().c_str()); - } - PyObject *res = PyList_New(2); - PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); - PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - PyList_SetItem(res,0,obj0); - PyList_SetItem(res,1,obj1); - return res; - } + // + PyObject *res = PyList_New(2); + PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); + PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + PyList_SetItem(res,0,obj0); + PyList_SetItem(res,1,obj1); + return res; + } PyObject *getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) { @@ -756,18 +811,18 @@ namespace ParaMEDMEM return ret; } - void translate(PyObject *vector) throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::translate : "; - const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->translate(vectorPtr); - } + void translate(PyObject *vector) throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::translate : "; + const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true); + self->translate(vectorPtr); + } void rotate(PyObject *center, double alpha) throw(INTERP_KERNEL::Exception) { @@ -845,10 +900,10 @@ namespace ParaMEDMEM %extend ParaMEDMEM::DataArrayInt { PyObject *getDifferentValues() const throw(INTERP_KERNEL::Exception) - { - std::set ret=self->getDifferentValues(); - return convertIntArrToPyList3(ret); - } + { + std::set ret=self->getDifferentValues(); + return convertIntArrToPyList3(ret); + } PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) { @@ -930,7 +985,7 @@ namespace ParaMEDMEM void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const throw(INTERP_KERNEL::Exception); void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) throw(INTERP_KERNEL::Exception); - virtual void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception); virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); virtual DataArrayInt *findBoundaryNodes() const; %extend @@ -966,111 +1021,74 @@ namespace ParaMEDMEM ret1->incrRef(); return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0); } + PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,((const int *)tmp)+size,keepCoords); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - MEDCouplingPointSet *ret=self->buildPartOfMySelf(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),keepCoords); - ret->setName(da2->getName().c_str()); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+szArr,keepCoords); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); } + PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,((const int *)tmp)+size,fullyIn); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn); - ret->setName(da2->getName().c_str()); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+szArr,fullyIn); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); } + PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,((const int *)tmp)+size,fullyIn); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn); - ret->setName(da2->getName().c_str()); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+szArr,fullyIn); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); } void renumberNodes(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodes(tmp,newNbOfNodes); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->renumberNodes(da2->getConstPointer(),newNbOfNodes); - } + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodes(tmp,newNbOfNodes); } + void renumberNodes2(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodes2(tmp,newNbOfNodes); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->renumberNodes2(da2->getConstPointer(),newNbOfNodes); - } + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodes2(tmp,newNbOfNodes); } + PyObject *findNodesOnLine(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) { int spaceDim=self->getSpaceDimension(); @@ -1109,6 +1127,7 @@ namespace ParaMEDMEM std::copy(nodes.begin(),nodes.end(),ret->getPointer()); return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); } + PyObject *getNodeIdsNearPoint(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) { double val; @@ -1119,16 +1138,13 @@ namespace ParaMEDMEM int spaceDim=self->getSpaceDimension(); const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoint : "; const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - std::vector tmp=self->getNodeIdsNearPoint(pos,eps); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)tmp.size(),1); - std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + DataArrayInt *ret=self->getNodeIdsNearPoint(pos,eps); return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); } PyObject *getNodeIdsNearPoints(PyObject *pt, int nbOfNodes, double eps) const throw(INTERP_KERNEL::Exception) { - std::vector c,cI; + DataArrayInt *c=0,*cI=0; // double val; DataArrayDouble *a; @@ -1140,69 +1156,32 @@ namespace ParaMEDMEM const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,nbOfNodes,spaceDim,true); self->getNodeIdsNearPoints(pos,nbOfNodes,eps,c,cI); PyObject *ret=PyTuple_New(2); - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - d0->alloc(c.size(),1); - d1->alloc(cI.size(),1); - std::copy(c.begin(),c.end(),d0->getPointer()); - std::copy(cI.begin(),cI.end(),d1->getPointer()); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - d0->incrRef(); - d1->incrRef(); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } PyObject *getNodeIdsNearPoints(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) { - std::vector c,cI; + DataArrayInt *c=0,*cI=0; int spaceDim=self->getSpaceDimension(); - void *da=0; - int res1=SWIG_ConvertPtr(pt,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewDblArr2(pt,&size); - int nbOfPoints=size/spaceDim; - if(size%spaceDim!=0) - { - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Invalid list length ! Must be a multiple of self.getSpaceDimension() !"); - } - self->getNodeIdsNearPoints(tmp,nbOfPoints,eps,c,cI); - } - else - { - DataArrayDouble *da2=reinterpret_cast< DataArrayDouble * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Not null DataArrayDouble instance expected !"); - da2->checkAllocated(); - int size=da2->getNumberOfTuples(); - int nbOfCompo=da2->getNumberOfComponents(); - if(nbOfCompo!=spaceDim) - { - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCellsContainingPoints : Invalid DataArrayDouble nb of components ! Expected same as self.getSpaceDimension() !"); - } - self->getNodeIdsNearPoints(da2->getConstPointer(),size,eps,c,cI); - } + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector bb; + int sw; + int nbOfTuples=-1; + const double *ptPtr=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::getNodeIdsNearPoints",spaceDim,true,nbOfTuples); + self->getNodeIdsNearPoints(ptPtr,nbOfTuples,eps,c,cI); + // PyObject *ret=PyTuple_New(2); - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - d0->alloc(c.size(),1); - d1->alloc(cI.size(),1); - std::copy(c.begin(),c.end(),d0->getPointer()); - std::copy(cI.begin(),cI.end(),d1->getPointer()); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - d0->incrRef(); - d1->incrRef(); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } PyObject *getCellsInBoundingBox(PyObject *bbox, double eps) const throw(INTERP_KERNEL::Exception) { - std::vector elems; - // - // double val; DataArrayDouble *a; DataArrayDoubleTuple *aa; @@ -1212,11 +1191,8 @@ namespace ParaMEDMEM const char msg[]="Python wrap of MEDCouplingPointSet::getCellsInBoundingBox : "; const double *tmp=convertObjToPossibleCpp5_Safe(bbox,sw,val,a,aa,bb,msg,spaceDim,2,true); // - self->getCellsInBoundingBox(tmp,eps,elems); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)elems.size(),1); - std::copy(elems.begin(),elems.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + DataArrayInt *elems=self->getCellsInBoundingBox(tmp,eps); + return SWIG_NewPointerObj(SWIG_as_voidptr(elems),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); } void duplicateNodesInCoords(PyObject *li) throw(INTERP_KERNEL::Exception) @@ -1408,11 +1384,12 @@ namespace ParaMEDMEM DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *computeSkin() const throw(INTERP_KERNEL::Exception); bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception); + bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception); DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); - DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception); + DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); @@ -1431,6 +1408,8 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception); std::string cppRepr() const throw(INTERP_KERNEL::Exception); + DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); + DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); @@ -1636,11 +1615,12 @@ namespace ParaMEDMEM void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) throw(INTERP_KERNEL::Exception) { - int sz; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&sz); - if(size>sz) + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + if(size>szArr) { - std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << sz << " !"; + std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << szArr << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } self->insertNextCell(type,size,tmp); @@ -1648,9 +1628,10 @@ namespace ParaMEDMEM void insertNextCell(INTERP_KERNEL::NormalizedCellType type, PyObject *li) throw(INTERP_KERNEL::Exception) { - int sz; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&sz); - self->insertNextCell(type,sz,tmp); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->insertNextCell(type,szArr,tmp); } DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception) @@ -1676,6 +1657,59 @@ namespace ParaMEDMEM PyList_SetItem(res,i,PyInt_FromLong(*iL)); return res; } + + static PyObject *ComputeSpreadZoneGraduallyFromSeed(PyObject *seed, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling=-1) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *seedPtr=convertObjToPossibleCpp1_Safe(seed,sw,szArr,iTypppArr,stdvecTyyppArr); + int nbOfDepthPeelingPerformed=0; + DataArrayInt *ret0=MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(seedPtr,seedPtr+szArr,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); + PyObject *res=PyTuple_New(2); + PyTuple_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(res,1,PyInt_FromLong(nbOfDepthPeelingPerformed)); + return res; + } + + PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *v0=0,*v1=0; + self->findCommonCells(compType,startCellId,v0,v1); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *v0=0,*v1=0; + MEDCouplingUMesh::FindCommonCellsAlg(compType,startCellId,nodal,nodalI,revNodal,revNodalI,v0,v1); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + PyObject *distanceToPoint(PyObject *point) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector bb; + int sw; + int nbOfCompo=self->getSpaceDimension(); + const double *pt=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::distanceToPoint",1,nbOfCompo,true); + // + int cellId=-1,nodeId=-1; + double ret0=self->distanceToPoint(pt,pt+nbOfCompo,cellId,nodeId); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(cellId)); + PyTuple_SetItem(ret,2,PyInt_FromLong(nodeId)); + return ret; + } + PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) { bool ret1; @@ -2073,16 +2107,6 @@ namespace ParaMEDMEM return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); } - PyObject *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception) - { - std::vector cells; - self->findAndCorrectBadOriented3DExtrudedCells(cells); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception) { double vec[3]; @@ -2445,7 +2469,15 @@ namespace ParaMEDMEM } }; - class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingMesh + class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh + { + public: + void updateTime() const throw(INTERP_KERNEL::Exception); + int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); + int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); + }; + + class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingStructuredMesh { public: static MEDCouplingCMesh *New(); @@ -2455,7 +2487,6 @@ namespace ParaMEDMEM const DataArrayDouble *coordsY=0, const DataArrayDouble *coordsZ=0) throw(INTERP_KERNEL::Exception); void setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); - void updateTime() const throw(INTERP_KERNEL::Exception); %extend { MEDCouplingCMesh() { @@ -2478,6 +2509,45 @@ namespace ParaMEDMEM } } }; + + class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh + { + public: + static MEDCouplingCurveLinearMesh *New(); + static MEDCouplingCurveLinearMesh *New(const char *meshName); + MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingCurveLinearMesh() + { + return MEDCouplingCurveLinearMesh::New(); + } + MEDCouplingCurveLinearMesh(const char *meshName) + { + return MEDCouplingCurveLinearMesh::New(meshName); + } + std::string __str__() const + { + return self->simpleRepr(); + } + DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getCoords(); + if(ret) + ret->incrRef(); + return ret; + } + void setNodeGridStructure(PyObject *gridStruct) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(gridStruct,sw,szArr,iTypppArr,stdvecTyyppArr); + self->setNodeGridStructure(tmp,tmp+szArr); + } + } + }; + } %extend ParaMEDMEM::MEDCouplingFieldDiscretizationKriging { @@ -2779,17 +2849,17 @@ namespace ParaMEDMEM return DataArrayDouble::New(); } - static DataArrayDouble *New(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + static DataArrayDouble *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) { const char *msg="ParaMEDMEM::DataArrayDouble::New : Available API are : \n-DataArrayDouble.New()\n--DataArrayDouble.New([1.,3.,4.])\n-DataArrayDouble.New([1.,3.,4.],3)\n-DataArrayDouble.New([1.,3.,4.,5.],2,2)\n-DataArrayDouble.New(5)\n-DataArrayDouble.New(5,2) !"; if(PyList_Check(elt0) || PyTuple_Check(elt0)) { - if(elt1) + if(nbOfTuples) { - if(PyInt_Check(elt1)) + if(PyInt_Check(nbOfTuples)) { - int nbOfTuples=PyInt_AS_LONG(elt1); - if(nbOfTuples<0) + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); if(elt2) { @@ -2799,8 +2869,8 @@ namespace ParaMEDMEM if(nbOfCompo<0) throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,nbOfCompo); - ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); ret->incrRef(); return ret; } @@ -2811,8 +2881,8 @@ namespace ParaMEDMEM {//DataArrayDouble.New([1.,3.,4.],3) MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int tmpp1=-1; - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,tmpp1); - ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); ret->incrRef(); return ret; } @@ -2832,20 +2902,20 @@ namespace ParaMEDMEM } else if(PyInt_Check(elt0)) { - int nbOfTuples=PyInt_AS_LONG(elt0); - if(nbOfTuples<0) + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); - if(elt1) + if(nbOfTuples) { if(!elt2) { - if(PyInt_Check(elt1)) + if(PyInt_Check(nbOfTuples)) {//DataArrayDouble.New(5,2) - int nbOfCompo=PyInt_AS_LONG(elt1); + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); if(nbOfCompo<0) throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); ret->incrRef(); return ret; } @@ -2858,7 +2928,7 @@ namespace ParaMEDMEM else {//DataArrayDouble.New(5) MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,1); + ret->alloc(nbOfTuples1,1); ret->incrRef(); return ret; } @@ -2867,9 +2937,9 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception(msg); } - DataArrayDouble(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) { - return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,elt1,elt2); + return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2); } std::string __str__() const @@ -2898,20 +2968,51 @@ namespace ParaMEDMEM { return self->iterator(); } - - void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) throw(INTERP_KERNEL::Exception) + + void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) { - double *tmp=new double[nbOfTuples*nbOfElsPerTuple]; - try + const char *msg="ParaMEDMEM::DataArrayDouble::setValues : Available API are : \n-DataArrayDouble.setValues([1.,3.,4.])\n-DataArrayDouble.setValues([1.,3.,4.],3)\n-DataArrayDouble.setValues([1.,3.,4.,5.],2,2)\n-DataArrayDouble.setValues([(1.,1.7),(3.,3.7),(4.,4.7)])\n !"; + if(PyList_Check(li) || PyTuple_Check(li)) { - fillArrayWithPyListDbl(li,tmp,nbOfTuples*nbOfElsPerTuple,0.,false); - } - catch(INTERP_KERNEL::Exception& e) - { - delete [] tmp; - throw e; + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayDouble.setValues([1.,3.,4.,5.],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive number of components !"); + std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,nbOfCompo); + self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayDouble.setValues([1.,3.,4.],3) + int tmpp1=-1; + std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,tmpp1); + self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {// DataArrayDouble.setValues([1.,3.,4.]) + int tmpp1=-1,tmpp2=-1; + std::vector tmp=fillArrayWithPyListDbl2(li,tmpp1,tmpp2); + self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } } - self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple); + else + throw INTERP_KERNEL::Exception(msg); } PyObject *getValues() throw(INTERP_KERNEL::Exception) @@ -3199,6 +3300,24 @@ namespace ParaMEDMEM return res; } + PyObject *distanceToTuple(PyObject *tuple) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector bb; + int sw; + int tupleId=-1,nbTuples=-1,nbOfCompo=self->getNumberOfComponents(); + const double *pt=convertObjToPossibleCpp5_Safe(tuple,sw,val,a,aa,bb,"Python wrap of DataArrayDouble::distanceToTuple",1,nbOfCompo,true); + // + int cellId=-1,nodeId=-1; + double ret0=self->distanceToTuple(pt,pt+nbOfCompo,tupleId); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tupleId)); + return ret; + } + void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception) { std::vector tmp; @@ -3246,14 +3365,11 @@ namespace ParaMEDMEM const char msg[]="Python wrap of DataArrayDouble::computeTupleIdsNearTuples : "; const double *pos=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,msg,nbComp,true,nbTuples); MEDCouplingAutoRefCountObjectPtr inpu=DataArrayDouble::New(); inpu->useArray(pos,false,CPP_DEALLOC,nbTuples,nbComp); - std::vector c,cI; + DataArrayInt *c=0,*cI=0; self->computeTupleIdsNearTuples(inpu,eps,c,cI); - DataArrayInt *ret0=DataArrayInt::New(),*ret1=DataArrayInt::New(); - ret0->alloc((int)c.size(),1); std::copy(c.begin(),c.end(),ret0->getPointer()); - ret1->alloc((int)cI.size(),1); std::copy(cI.begin(),cI.end(),ret1->getPointer()); PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } @@ -4176,20 +4292,12 @@ namespace ParaMEDMEM PyObject *computeTupleIdsNearTuples(const DataArrayDouble *other, double eps) { - std::vector c,cI; + DataArrayInt *c=0,*cI=0; // self->computeTupleIdsNearTuples(other,eps,c,cI); PyObject *ret=PyTuple_New(2); - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - d0->alloc(c.size(),1); - d1->alloc(cI.size(),1); - std::copy(c.begin(),c.end(),d0->getPointer()); - std::copy(cI.begin(),cI.end(),d1->getPointer()); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - d0->incrRef(); - d1->incrRef(); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); return ret; } }; @@ -4490,28 +4598,28 @@ namespace ParaMEDMEM return DataArrayInt::New(); } - static DataArrayInt *New(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + static DataArrayInt *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) { const char *msg="ParaMEDMEM::DataArrayInt::New : Available API are : \n-DataArrayInt.New()\n--DataArrayInt.New([1,3,4])\n-DataArrayInt.New([1,3,4],3)\n-DataArrayInt.New([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n-DataArrayInt.New(5,2) !"; if(PyList_Check(elt0) || PyTuple_Check(elt0)) { - if(elt1) + if(nbOfTuples) { - if(PyInt_Check(elt1)) + if(PyInt_Check(nbOfTuples)) { - int nbOfTuples=PyInt_AS_LONG(elt1); - if(nbOfTuples<0) + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(elt2) + if(nbOfComp) { - if(PyInt_Check(elt2)) + if(PyInt_Check(nbOfComp)) {//DataArrayInt.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(elt2); + int nbOfCompo=PyInt_AS_LONG(nbOfComp); if(nbOfCompo<0) throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,nbOfCompo); - ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); ret->incrRef(); return ret; } @@ -4522,8 +4630,8 @@ namespace ParaMEDMEM {//DataArrayInt.New([1,3,4],3) MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,tmpp1); - ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); ret->incrRef(); return ret; } @@ -4543,20 +4651,20 @@ namespace ParaMEDMEM } else if(PyInt_Check(elt0)) { - int nbOfTuples=PyInt_AS_LONG(elt0); - if(nbOfTuples<0) + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(elt1) + if(nbOfTuples) { - if(!elt2) + if(!nbOfComp) { - if(PyInt_Check(elt1)) + if(PyInt_Check(nbOfTuples)) {//DataArrayInt.New(5,2) - int nbOfCompo=PyInt_AS_LONG(elt1); + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); if(nbOfCompo<0) throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); ret->incrRef(); return ret; } @@ -4569,7 +4677,7 @@ namespace ParaMEDMEM else {//DataArrayInt.New(5) MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); + ret->alloc(nbOfTuples1,1); ret->incrRef(); return ret; } @@ -4578,9 +4686,9 @@ namespace ParaMEDMEM throw INTERP_KERNEL::Exception(msg); } - DataArrayInt(PyObject *elt0, PyObject *elt1=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) { - return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,elt1,elt2); + return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,nbOfTuples,nbOfComp); } std::string __str__() const @@ -4609,30 +4717,73 @@ namespace ParaMEDMEM { return self->iterator(); } - - static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI) throw(INTERP_KERNEL::Exception) + + PyObject *accumulate() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr tmp=new int[sz]; + self->accumulate(tmp); + return convertIntArrToPyList(tmp,sz); + } + + static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception) { int newNbOfTuples=-1; - DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arr,arrI,newNbOfTuples); + int szArr,szArrI,sw,iTypppArr,iTypppArrI; + std::vector stdvecTyyppArr,stdvecTyyppArrI; + const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr); + const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI); + DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples); PyObject *ret=PyTuple_New(2); PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples)); return ret; } - void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) throw(INTERP_KERNEL::Exception) + void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) { - int *tmp=new int[nbOfTuples*nbOfElsPerTuple]; - try - { - fillArrayWithPyListInt(li,tmp,nbOfTuples*nbOfElsPerTuple,0,false); - } - catch(INTERP_KERNEL::Exception& e) + const char *msg="ParaMEDMEM::DataArrayInt::setValues : Available API are : \n-DataArrayInt.setValues([1,3,4])\n-DataArrayInt.setValues([1,3,4],3)\n-DataArrayInt.setValues([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n !"; + if(PyList_Check(li) || PyTuple_Check(li)) { - delete [] tmp; - throw e; + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayInt.setValues([1,3,4,5],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive number of components !"); + std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,nbOfCompo); + self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayInt.setValues([1,3,4],3) + int tmpp1=-1; + std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,tmpp1); + self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {// DataArrayInt.setValues([1,3,4]) + int tmpp1=-1,tmpp2=-1; + std::vector tmp=fillArrayWithPyListInt2(li,tmpp1,tmpp2); + self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } } - self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple); + else + throw INTERP_KERNEL::Exception(msg); } PyObject *getValues() throw(INTERP_KERNEL::Exception) @@ -6347,14 +6498,16 @@ namespace ParaMEDMEM class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField { public: - static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME); + static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME); void setTimeUnit(const char *unit); const char *getTimeUnit() const; + void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; + void writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; MEDCouplingFieldDouble *deepCpy() const; @@ -6362,6 +6515,7 @@ namespace ParaMEDMEM TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception); double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); + void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); @@ -6439,12 +6593,12 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); %extend { - MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME) + MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME) { return MEDCouplingFieldDouble::New(type,td); } - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME) + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME) { return MEDCouplingFieldDouble::New(ft,td); } @@ -7126,19 +7280,6 @@ namespace ParaMEDMEM }; } -%inline %{ - PyObject *MEDCouplingVersionMajMinRel() - { - int tmp0=0,tmp1=0,tmp2=0; - MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } -%} - %pythoncode %{ import os __filename=os.environ.get('PYTHONSTARTUP') diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py index 5c8042f5e..1998d7fdf 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py @@ -285,6 +285,39 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); pass pass + + # Bug when source mesh is not homogeneously oriented in source mesh + def testNonRegressionNonHomegenousOrriented3DCells(self): + csrc=DataArrayDouble([-0.15240000188350677,0,0,-0.1086929515004158,0,0,-0.15240000188350677,0.018142856657505035,0,-0.13054648041725159,0.0090714283287525177,0.019050000235438347,-0.13054648041725159,0.0090714283287525177,0],5,3) + src1=MEDCouplingUMesh("src",3) ; src1.allocateCells(0) ; src1.insertNextCell(NORM_TETRA4,[0,1,4,3]) ; src1.insertNextCell(NORM_TETRA4,[2,0,4,3]) + src2=MEDCouplingUMesh("src",3) ; src2.allocateCells(0) ; src2.insertNextCell(NORM_TETRA4,[0,4,1,3]) ; src2.insertNextCell(NORM_TETRA4,[2,0,4,3]) + src1.setCoords(csrc) ; src2.setCoords(csrc) + ctrg=DataArrayDouble([-0.15240000188350677,-0.038100000470876694,0,0.32379999756813049,-0.038100000470876694,0,-0.15240000188350677,0.076200000941753387,0,0.32379999756813049,0.076200000941753387,0,-0.15240000188350677,-0.038100000470876694,0.076200000941753387,0.32379999756813049,-0.038100000470876694,0.076200000941753387,-0.15240000188350677,0.076200000941753387,0.076200000941753387,0.32379999756813049,0.076200000941753387,0.076200000941753387],8,3) + trg=MEDCouplingUMesh("trg",3) ; trg.allocateCells(0) ; trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6]) + trg.setCoords(ctrg) + rem1=MEDCouplingRemapper() ; rem1.setSplittingPolicy(PLANAR_FACE_5) ; rem1.prepare(src1,trg,"P0P0") + rem2=MEDCouplingRemapper() ; rem2.setSplittingPolicy(PLANAR_FACE_5) ; rem2.prepare(src1,trg,"P0P0") + mat1=rem1.getCrudeMatrix() ; mat2=rem2.getCrudeMatrix() + self.assertEqual(1,len(mat1)) ; self.assertEqual(1,len(mat2)) + self.assertEqual(mat1[0].keys(),mat2[0].keys()) ; self.assertEqual([0,1],mat1[0].keys()) + self.assertAlmostEqual(1.25884108122e-06,mat1[0][0],16) ; self.assertAlmostEqual(1.25884108122e-06,mat2[0][0],16) + self.assertAlmostEqual(1.25884086663e-06,mat1[0][1],16) ; self.assertAlmostEqual(1.25884086663e-06,mat2[0][1],16) + # + d=DataArrayDouble([13.45,27.67],2,1) + f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f1.setMesh(src1) ; f1.setArray(d) ; f1.setNature(RevIntegral) + f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f2.setMesh(src2) ; f2.setArray(d) ; f2.setNature(RevIntegral) + f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) + expected1=DataArrayDouble([0.012480539537637884]) + self.assertTrue(f11.getArray().isEqual(expected1,1e-15)) + self.assertTrue(f22.getArray().isEqual(expected1,1e-15)) + # + f1.setNature(Integral) ; f2.setNature(Integral) + f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) + # + expected2=DataArrayDouble([41.12]) + self.assertTrue(f11.getArray().isEqual(expected2,1e-13)) + self.assertTrue(f22.getArray().isEqual(expected2,1e-13)) + pass def build2DSourceMesh_1(self): sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index c16812429..faac75832 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -30,6 +30,8 @@ static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner); + if(dynamic_cast(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh,owner); if(!ret) throw INTERP_KERNEL::Exception("Not recognized type of mesh on downcast !"); return ret; @@ -453,6 +455,8 @@ static std::vector fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, PyObject *o=PyList_GetItem(pyLi,i); fillArrayWithPyListInt3(o,size2,ret); } + if(size1==0) + size2=1; } else if(PyTuple_Check(pyLi)) { @@ -462,6 +466,8 @@ static std::vector fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, PyObject *o=PyTuple_GetItem(pyLi,i); fillArrayWithPyListInt3(o,size2,ret); } + if(size1==0) + size2=1; } else throw INTERP_KERNEL::Exception("fillArrayWithPyListInt2 : Unrecognized type ! Should be a tuple or a list !"); @@ -470,66 +476,6 @@ static std::vector fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, return ret; } -/* - * will become obsolete -> fillArrayWithPyListInt2 - */ -static void fillArrayWithPyListInt(PyObject *pyLi, int *arrToFill, int sizeOfArray, int dftVal, bool chckSize) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - if(chckSize) - if(size!=sizeOfArray) - { - std::ostringstream oss; oss << "fillArrayWithPyListInt : List expected to be of size " << sizeOfArray << " but the size is " << size << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl PyObject *o=PyList_GetItem(pyLi,i); fillArrayWithPyListDbl3(o,size2,ret); } + if(size1==0) + size2=1; } else if(PyTuple_Check(pyLi)) { @@ -705,6 +653,8 @@ static std::vector fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl PyObject *o=PyTuple_GetItem(pyLi,i); fillArrayWithPyListDbl3(o,size2,ret); } + if(size1==0) + size2=1; } else throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl2 : Unrecognized type ! Should be a tuple or a list !"); @@ -713,77 +663,6 @@ static std::vector fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTupl return ret; } -/* - * will become obsolete -> fillArrayWithPyListDbl2 - */ -static void fillArrayWithPyListDbl(PyObject *pyLi, double *arrToFill, int sizeOfArray, double dftVal, bool chckSize) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - if(chckSize) - if(size!=sizeOfArray) - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl : List expected to be of size " << sizeOfArray << " but the size is " << size << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh") template static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector& ret) @@ -1107,13 +986,14 @@ static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& } if(PySlice_Check(value)) { - Py_ssize_t strt,stp,step; + Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(value); if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0) - { - std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elemnts is : " << nbelem; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + if(nbelem!=0 || strt!=0 || stp!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } p.first=strt; p.second.first=stp; p.second.second=step; @@ -1197,13 +1077,14 @@ static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& } if(PySlice_Check(value)) { - Py_ssize_t strt,stp,step; + Py_ssize_t strt=2,stp=2,step=2; PySliceObject *oC=reinterpret_cast(value); if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0) - { - std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elemnts is : " << nbelem; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + if(nbelem!=0 || strt!=0 || stp!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elements is : " << nbelem; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } p.first=strt; p.second.first=stp; p.second.second=step; diff --git a/src/MEDLoader/MEDFileData.cxx b/src/MEDLoader/MEDFileData.cxx index 61f1429f3..fbabd4709 100644 --- a/src/MEDLoader/MEDFileData.cxx +++ b/src/MEDLoader/MEDFileData.cxx @@ -32,6 +32,29 @@ MEDFileData *MEDFileData::New() return new MEDFileData; } +MEDFileData *MEDFileData::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr fields; + if((const MEDFileFields *)_fields) + fields=_fields->deepCpy(); + MEDCouplingAutoRefCountObjectPtr meshes; + if((const MEDFileMeshes *)_meshes) + meshes=_meshes->deepCpy(); + MEDCouplingAutoRefCountObjectPtr ret=MEDFileData::New(); + ret->_fields=fields; ret->_meshes=meshes; + return ret.retn(); +} + +std::size_t MEDFileData::getHeapMemorySize() const +{ + std::size_t ret=0; + if((const MEDFileFields *)_fields) + ret+=_fields->getHeapMemorySize(); + if((const MEDFileMeshes *)_meshes) + ret+=_meshes->getHeapMemorySize(); + return ret; +} + MEDFileFields *MEDFileData::getFields() const { return const_cast(static_cast(_fields)); diff --git a/src/MEDLoader/MEDFileData.hxx b/src/MEDLoader/MEDFileData.hxx index 64b946ec0..c732aad9d 100644 --- a/src/MEDLoader/MEDFileData.hxx +++ b/src/MEDLoader/MEDFileData.hxx @@ -35,6 +35,8 @@ namespace ParaMEDMEM public: static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileData *New(); + MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; MEDFileFields *getFields() const; MEDFileMeshes *getMeshes() const; void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 70d126a7d..a94f55473 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -100,6 +100,16 @@ MEDFileFieldLoc::MEDFileFieldLoc(const char *locName, INTERP_KERNEL::NormalizedC _nb_gauss_pt=_w.size(); } +MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const +{ + return new MEDFileFieldLoc(*this); +} + +std::size_t MEDFileFieldLoc::getHeapMemorySize() const +{ + return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity(); +} + void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const { static const char OFF7[]="\n "; @@ -390,6 +400,18 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const return new MEDFileFieldPerMeshPerTypePerDisc(other); } +std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySize() const +{ + return _profile.capacity()+_localization.capacity()+5*sizeof(int); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerTypePerDisc(*this); + ret->_father=father; + return ret.retn(); +} + MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt) throw(INTERP_KERNEL::Exception) try:_type(atype),_father(fath) { @@ -919,6 +941,27 @@ MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh return new MEDFileFieldPerMeshPerType(fath,geoType); } +std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySize() const +{ + std::size_t ret=_field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerType(*this); + ret->_father=father; + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) + { + if((const MEDFileFieldPerMeshPerTypePerDisc *)*it) + ret->_field_pm_pt_pd[i]=(*it)->deepCpy((MEDFileFieldPerMeshPerType *)ret); + } + return ret.retn(); +} + void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) { std::vector pos=addNewEntryIfNecessary(field,offset,nbOfCells); @@ -1426,6 +1469,28 @@ MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileField1TSWithoutSDA *fath, c return new MEDFileFieldPerMesh(fath,mesh); } +std::size_t MEDFileFieldPerMesh::getHeapMemorySize() const +{ + std::size_t ret=_mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + if((const MEDFileFieldPerMeshPerType *)*it) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileField1TSWithoutSDA *father) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this); + ret->_father=father; + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) + { + if((const MEDFileFieldPerMeshPerType *)*it) + ret->_field_pm_pt[i]=(*it)->deepCpy((MEDFileFieldPerMesh *)(ret)); + } + return ret.retn(); +} + void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const { std::string startLine(bkOffset,' '); @@ -1925,7 +1990,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField t return finishField(type,glob,dads,locs,mesh,isPfl); } else - return finishField3(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl); + return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl); } } @@ -2084,8 +2149,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const } } // - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -2110,22 +2174,20 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, cons m2->setName(mesh->getName()); MEDCouplingAutoRefCountObjectPtr ret=finishField(type,glob,dads,locs,m2,isPfl); isPfl=true; - ret->incrRef(); - return ret; + return ret.retn(); } /*! * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles. */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlobsReal *glob, - const std::vector >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob, + const std::vector >& dads, const std::vector& locs, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception) { if(da->isIdentity()) { int nbOfTuples=da->getNumberOfTuples(); - const std::vector geoTypes2(1,INTERP_KERNEL::NORM_ERROR); - if(nbOfTuples==ComputeNbOfElems(glob,ON_NODES,geoTypes2,dads,locs))//No problem for NORM_ERROR because it is in context of node + if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node return finishField(ON_NODES,glob,dads,locs,mesh,isPfl); } // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1. @@ -2144,8 +2206,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlob meshuc->finishInsertingCells(); ret->setMesh(meshuc); ret->checkCoherency(); - ret->incrRef(); - return ret; + return ret.retn(); } } // @@ -2162,12 +2223,11 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField3(const MEDFileFieldGlob ret->getArray()->renumberInPlace(da3->getConstPointer()); mesh2->setName(mesh->getName()); ret->setMesh(mesh2); - ret->incrRef(); - return ret; + return ret.retn(); } else { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishField3 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!"; + std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!"; oss << "So it is impossible to return a well definied MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl; oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl; oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl; @@ -2201,8 +2261,7 @@ DataArrayDouble *MEDFileFieldPerMesh::finishField4(const std::vectorsetInfoOnComponent(i,infos[i].c_str()); safePfl->incrRef(); - da->incrRef(); - return da; + return da.retn(); } MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception):_mesh_iteration(meshIteration),_mesh_order(meshOrder), @@ -2361,6 +2420,34 @@ MEDFileFieldGlobs *MEDFileFieldGlobs::New() return new MEDFileFieldGlobs; } +std::size_t MEDFileFieldGlobs::getHeapMemorySize() const +{ + std::size_t ret=_file_name.capacity()+_pfls.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) + ret+=(*it)->getHeapMemorySize(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldGlobs(*this); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) + { + if((const DataArrayInt *)*it) + ret->_pfls[i]=(*it)->deepCpy(); + } + i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) + { + if((const MEDFileFieldLoc*)*it) + ret->_locs[i]=(*it)->deepCpy(); + } + return ret.retn(); +} + MEDFileFieldGlobs::MEDFileFieldGlobs(const char *fname):_file_name(fname) { } @@ -2720,6 +2807,14 @@ MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New() { } +std::size_t MEDFileFieldGlobsReal::getHeapMemorySize() const +{ + std::size_t ret=0; + if((const MEDFileFieldGlobs *)_globals) + ret+=_globals->getHeapMemorySize(); + return ret; +} + void MEDFileFieldGlobsReal::simpleRepr(std::ostream& oss) const { oss << "Globals information on fields :" << "\n*******************************\n\n"; @@ -2739,6 +2834,13 @@ void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other) _globals=other._globals; } +void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) +{ + _globals=other._globals; + if((const MEDFileFieldGlobs *)_globals) + _globals=other._globals->deepCpy(); +} + void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception) { _globals->appendGlobs(*other._globals,eps); @@ -3515,7 +3617,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtLevel(TypeOfField t if(mName==0) mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); else - mm=MEDFileMesh::New(glob->getFileName(),mName,-1,-1); + mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm); } @@ -3535,7 +3637,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtTopLevel(TypeOfFiel if(mName==0) mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); else - mm=MEDFileMesh::New(glob->getFileName(),mName,-1,-1); + mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); int absDim=getDimension(); int meshDimRelToMax=absDim-mm->getMeshDimension(); return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm); @@ -3555,8 +3657,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF case 0: { //no need to test _field_per_mesh.empty() because geMeshName has already done it - ret->incrRef(); - return ret; + return ret.retn(); } case 3: case 1: @@ -3575,10 +3676,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF ret->renumberCells(cellRenum->getConstPointer(),true); } if(renumPol==1) - { - ret->incrRef(); - return ret; - } + return ret.retn(); } case 2: { @@ -3596,8 +3694,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF MEDCouplingAutoRefCountObjectPtr nodeRenumSafe=nodeRenum->checkAndPreparePermutation(); ret->renumberNodes(nodeRenumSafe->getConstPointer()); } - ret->incrRef(); - return ret; + return ret.retn(); } default: throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !"); @@ -3720,6 +3817,30 @@ const MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TSWithoutSDA::getLeafGiven return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); } +std::size_t MEDFileField1TSWithoutSDA::getHeapMemorySize() const +{ + std::size_t ret=_dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); + if((const DataArrayDouble *)_arr) + ret+=_arr->getHeapMemorySize(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TSWithoutSDA(*this); + if((const DataArrayDouble *)_arr) + ret->_arr=_arr->deepCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,i++) + { + if((const MEDFileFieldPerMesh *)*it) + ret->_field_per_mesh[i]=(*it)->deepCpy((MEDFileField1TSWithoutSDA *)ret); + } + return ret.retn(); +} + DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() { DataArrayDouble *ret=_arr; @@ -3747,9 +3868,9 @@ MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldNam /*! * \warning this is a shallow copy constructor */ -MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool deepCpy) +MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) { - return new MEDFileField1TS(other,deepCpy); + return new MEDFileField1TS(other,shallowCopyOfContent); } MEDFileField1TS *MEDFileField1TS::New() @@ -3775,8 +3896,8 @@ void MEDFileField1TS::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) std::string info=getInfo()[i]; std::string c,u; MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str); - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str); + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str); } if(getName().empty()) throw INTERP_KERNEL::Exception("MEDFileField1TS::write : MED file does not accept field with empty name !"); @@ -3867,9 +3988,9 @@ catch(INTERP_KERNEL::Exception& e) /*! * \warning this is a shallow copy constructor */ -MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool deepCpy) +MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) { - if(!deepCpy) + if(!shallowCopyOfContent) { const MEDFileField1TSWithoutSDA *otherPtr(&other); otherPtr->incrRef(); @@ -4095,6 +4216,23 @@ void MEDFileField1TS::setLocNameOnLeaf(const char *mName, INTERP_KERNEL::Normali } } +std::size_t MEDFileField1TS::getHeapMemorySize() const +{ + std::size_t ret=0; + if((const MEDFileField1TSWithoutSDA *)_content) + ret+=_content->getHeapMemorySize(); + return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); +} + +MEDFileField1TS *MEDFileField1TS::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS(*this); + if((const MEDFileField1TSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); +} + int MEDFileField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) { return _content->copyTinyInfoFrom(field); @@ -4293,9 +4431,32 @@ try:_name(fieldName),_infos(infos),_field_type(ft) finishLoading(fid,nbOfStep); } catch(INTERP_KERNEL::Exception& e) - { - throw e; - } +{ + throw e; +} + +std::size_t MEDFileFieldMultiTSWithoutSDA::getHeapMemorySize() const +{ + std::size_t ret=_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) + ret+=(*it).capacity(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + if((const MEDFileField1TSWithoutSDA *)(*it)) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTSWithoutSDA(*this); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + if((const MEDFileField1TSWithoutSDA *)*it) + ret->_time_steps[i]=(*it)->deepCpy(); + } + return ret.retn(); +} const std::vector& MEDFileFieldMultiTSWithoutSDA::getInfo() const throw(INTERP_KERNEL::Exception) { @@ -4523,8 +4684,8 @@ void MEDFileFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& std::string info=infos[i]; std::string c,u; MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); } if(_name.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::write : MED file does not accept field with empty name !"); @@ -4828,9 +4989,26 @@ MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char * return new MEDFileFieldMultiTS(fileName,fieldName); } -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy) +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +{ + return new MEDFileFieldMultiTS(other,shallowCopyOfContent); +} + +std::size_t MEDFileFieldMultiTS::getHeapMemorySize() const { - return new MEDFileFieldMultiTS(other,deepCpy); + std::size_t ret=0; + if((const MEDFileFieldMultiTSWithoutSDA*)_content) + ret+=_content->getHeapMemorySize(); + return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); +} + +MEDFileFieldMultiTS *MEDFileFieldMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(*this); + if((const MEDFileFieldMultiTSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); } MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception) @@ -4838,8 +5016,7 @@ MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const throw(INTE const MEDFileField1TSWithoutSDA *item=_content->getTimeStepAtPos2(pos); MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(*item,false); ret->shallowCpyGlobs(*this); - ret->incrRef(); - return ret; + return ret.retn(); } MEDFileField1TS *MEDFileFieldMultiTS::getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception) @@ -5014,9 +5191,9 @@ catch(INTERP_KERNEL::Exception& e) throw e; } -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy) +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) { - if(!deepCpy) + if(!shallowCopyOfContent) { const MEDFileFieldMultiTSWithoutSDA *otherPtr(&other); otherPtr->incrRef(); @@ -5195,6 +5372,28 @@ MEDFileFields *MEDFileFields::New(const char *fileName) throw(INTERP_KERNEL::Exc return new MEDFileFields(fileName); } +std::size_t MEDFileFields::getHeapMemorySize() const +{ + std::size_t ret=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + if((const MEDFileFieldMultiTSWithoutSDA *)*it) + ret+=(*it)->getHeapMemorySize(); + return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); +} + +MEDFileFields *MEDFileFields::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFields(*this); + std::size_t i=0; + for( std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + if((const MEDFileFieldMultiTSWithoutSDA*)*it) + ret->_fields[i]=(*it)->deepCpy(); + } + ret->deepCpyGlobs(*this); + return ret.retn(); +} + int MEDFileFields::getNumberOfFields() const { return _fields.size(); @@ -5482,8 +5681,7 @@ MEDFileFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const throw(INTERP_KERN const MEDFileFieldMultiTSWithoutSDA *fmts=_fields[i]; MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldMultiTS::New(*fmts,false); ret->shallowCpyGlobs(*this); - ret->incrRef(); - return ret; + return ret.retn(); } MEDFileFieldMultiTS *MEDFileFields::getFieldWithName(const char *fieldName) const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index 6ddb6f209..cf17442a7 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -54,6 +54,8 @@ namespace ParaMEDMEM static MEDFileFieldLoc *New(med_idt fid, const char *locName); static MEDFileFieldLoc *New(med_idt fid, int id); static MEDFileFieldLoc *New(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); + std::size_t getHeapMemorySize() const; + MEDFileFieldLoc *deepCpy() const; int MEDLOADER_EXPORT getNbOfGaussPtPerCell() const { return _nb_gauss_pt; } void MEDLOADER_EXPORT writeLL(med_idt fid) const; std::string MEDLOADER_EXPORT repr() const; @@ -92,6 +94,8 @@ namespace ParaMEDMEM static MEDFileFieldPerMeshPerTypePerDisc *NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt) throw(INTERP_KERNEL::Exception); static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId); static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other); + std::size_t getHeapMemorySize() const; + MEDFileFieldPerMeshPerTypePerDisc *deepCpy(MEDFileFieldPerMeshPerType *father) const throw(INTERP_KERNEL::Exception); void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); @@ -164,6 +168,8 @@ namespace ParaMEDMEM public: static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception); static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileFieldPerMeshPerType *deepCpy(MEDFileFieldPerMesh *father) const throw(INTERP_KERNEL::Exception); void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); @@ -217,6 +223,8 @@ namespace ParaMEDMEM public: static MEDFileFieldPerMesh *New(MEDFileField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileFieldPerMesh *deepCpy(MEDFileField1TSWithoutSDA *_father) const throw(INTERP_KERNEL::Exception); void simpleRepr(int bkOffset,std::ostream& oss, int id) const; void copyTinyInfoFrom(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception); @@ -262,9 +270,9 @@ namespace ParaMEDMEM const std::vector< std::pair >& dads, const std::vector& locs, const std::vector& geoTypes, const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *finishField3(const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *finishFieldNode2(const MEDFileFieldGlobsReal *glob, + const std::vector< std::pair >& dads, const std::vector& locs, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception); DataArrayDouble *finishField4(const std::vector< std::pair >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const throw(INTERP_KERNEL::Exception); void assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) throw(INTERP_KERNEL::Exception); static void SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, @@ -289,6 +297,8 @@ namespace ParaMEDMEM public: static MEDFileFieldGlobs *New(const char *fname); static MEDFileFieldGlobs *New(); + std::size_t getHeapMemorySize() const; + MEDFileFieldGlobs *deepCpy() const throw(INTERP_KERNEL::Exception); void simpleRepr(std::ostream& oss) const; void appendGlobs(const MEDFileFieldGlobs& other, double eps) throw(INTERP_KERNEL::Exception); void loadProfileInFile(med_idt fid, int id, const char *pflName) throw(INTERP_KERNEL::Exception); @@ -343,8 +353,10 @@ namespace ParaMEDMEM public: MEDFileFieldGlobsReal(const char *fname); MEDFileFieldGlobsReal(); + std::size_t getHeapMemorySize() const; void simpleRepr(std::ostream& oss) const; void shallowCpyGlobs(const MEDFileFieldGlobsReal& other); + void deepCpyGlobs(const MEDFileFieldGlobsReal& other); void appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception); virtual std::vector getPflsReallyUsed() const = 0; virtual std::vector getLocsReallyUsed() const = 0; @@ -460,6 +472,8 @@ namespace ParaMEDMEM public: MEDFileField1TSWithoutSDA(); MEDFileField1TSWithoutSDA(const char *fieldName, int csit, int fieldtype, int iteration, int order, const std::vector& infos); + MEDFileField1TSWithoutSDA *deepCpy() const throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; DataArrayDouble *getOrCreateAndGetArray(); const DataArrayDouble *getOrCreateAndGetArray() const; protected: @@ -483,7 +497,7 @@ namespace ParaMEDMEM { public: static MEDFileField1TS *New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool deepCpy); + static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); static MEDFileField1TS *New(); std::string simpleRepr() const; void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); @@ -498,6 +512,8 @@ namespace ParaMEDMEM void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); // direct forwarding to MEDFileField1TSWithoutSDA instance _content public: + std::size_t getHeapMemorySize() const; + MEDFileField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); int copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); int getDimension() const; int getIteration() const; @@ -544,7 +560,7 @@ namespace ParaMEDMEM private: void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool deepCpy); + MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); MEDFileField1TS(); protected: MEDCouplingAutoRefCountObjectPtr _content; @@ -555,6 +571,8 @@ namespace ParaMEDMEM public: static MEDFileFieldMultiTSWithoutSDA *New(med_idt fid, const char *fieldName, int id, int ft, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileFieldMultiTSWithoutSDA *deepCpy() const throw(INTERP_KERNEL::Exception); int getNumberOfTS() const; void eraseEmptyTS() throw(INTERP_KERNEL::Exception); void eraseTimeStepIds(const int *startIds, const int *endIds) throw(INTERP_KERNEL::Exception); @@ -618,7 +636,9 @@ namespace ParaMEDMEM static MEDFileFieldMultiTS *New(); static MEDFileFieldMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); - static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy); + static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + std::size_t getHeapMemorySize() const; + MEDFileFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); // MEDFileField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); MEDFileField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); @@ -669,7 +689,7 @@ std::vector< std::vector > getFieldSplitedByType2(int iterati MEDCouplingAutoRefCountObjectPtr getContent(); private: MEDFileFieldMultiTS(); - MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool deepCpy); + MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); MEDFileFieldMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception); MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); protected: @@ -698,6 +718,8 @@ std::vector< std::vector > getFieldSplitedByType2(int iterati public: static MEDFileFields *New(); static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 5c5ccd8f8..987e61bd0 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -38,6 +38,20 @@ MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.) { } +std::size_t MEDFileMesh::getHeapMemorySize() const +{ + std::size_t ret=_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity(); + for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string); + for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + ret+=(*it2).capacity(); + } + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + ret+=(*it).first.capacity()+sizeof(int); + return ret; +} + MEDFileMesh *MEDFileMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception) { std::vector ms=MEDLoader::GetMeshNames(fileName); @@ -58,15 +72,19 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName) throw(INTERP_KERNEL::Excepti { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it); - ret->incrRef(); - return (MEDFileUMesh *)ret; + return (MEDFileUMesh *)ret.retn(); } case CARTESIAN: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it); - ret->incrRef(); - return (MEDFileCMesh *)ret; + return (MEDFileCMesh *)ret.retn(); + } + case CURVE_LINEAR: + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); + ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it); + return (MEDFileCMesh *)ret.retn(); } default: { @@ -90,15 +108,13 @@ MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, i { MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); ret->loadUMeshFromFile(fid,mName,dt,it); - ret->incrRef(); - return (MEDFileUMesh *)ret; + return (MEDFileUMesh *)ret.retn(); } case CARTESIAN: { MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); ret->loadCMeshFromFile(fid,mName,dt,it); - ret->incrRef(); - return (MEDFileCMesh *)ret; + return (MEDFileCMesh *)ret.retn(); } default: { @@ -749,6 +765,26 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot } } +void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception) +{ + ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); +} + +void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception) +{ + std::string fam(familyNameToChange); + for(std::map >::iterator it=groups.begin();it!=groups.end();it++) + { + std::vector& fams((*it).second); + std::vector::iterator it2=std::find(fams.begin(),fams.end(),fam); + if(it2!=fams.end()) + { + fams.erase(it2); + fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end()); + } + } +} + /*! * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId. * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false. @@ -759,9 +795,22 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *ot */ std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception) { - std::vector famAlreadyExisting(_families.size()); + return FindOrCreateAndGiveFamilyWithId(_families,id,created); +} + +/*! + * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId. + * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false. + * If there is no family whose family id is equal to 'id' a family is created with a name different from those + * already existing. In this case 'created' will be returned with a value set to true, and internal state + * will be modified. + * This method will throws an exception if it is not possible to create a unique family name. + */ +std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created) throw(INTERP_KERNEL::Exception) +{ + std::vector famAlreadyExisting(families.size()); int ii=0; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++,ii++) + for(std::map::const_iterator it=families.begin();it!=families.end();it++,ii++) { if((*it).second!=id) { @@ -776,7 +825,7 @@ std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) created=true; std::ostringstream oss; oss << "Family_" << id; std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting); - _families[ret]=id; + families[ret]=id; return ret; } @@ -847,6 +896,24 @@ int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception) return ret; } +int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception) +{ + int m1=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + m1=std::max((*it).second,m1); + int m2=getMaxFamilyIdInArrays(); + return std::max(m1,m2); +} + +int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception) +{ + int m1=std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + m1=std::min((*it).second,m1); + int m2=getMinFamilyIdInArrays(); + return std::min(m1,m2); +} + DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); @@ -855,7 +922,7 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERN v.insert((*it).second); ret->alloc((int)v.size(),1); std::copy(v.begin(),v.end(),ret->getPointer()); - ret->incrRef(); return ret; + return ret.retn(); } /*! @@ -1006,7 +1073,7 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception) /*! * This method normalizes fam id with the following policy. * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0 - * This policy is those used by SMESH and Trio and that is the opposite of those in MED file. + * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio. * This method will throw an exception if a same family id is detected in different level. */ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception) @@ -1302,6 +1369,21 @@ void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL } } } + if(_desc_name.empty()) + _desc_name=m->getDescription(); + else + { + std::string name(m->getDescription()); + if(!name.empty()) + { + if(_desc_name!=name) + { + std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '"; + oss << name << "' ! Names must match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } } void MEDFileMesh::getFamilyRepr(std::ostream& oss) const @@ -1346,6 +1428,50 @@ MEDFileUMesh *MEDFileUMesh::New() return new MEDFileUMesh; } +std::size_t MEDFileUMesh::getHeapMemorySize() const +{ + std::size_t ret=MEDFileMesh::getHeapMemorySize(); + if((const DataArrayDouble*)_coords) + ret+=_coords->getHeapMemorySize(); + if((const DataArrayInt *)_fam_coords) + ret+=_fam_coords->getHeapMemorySize(); + if((const DataArrayInt *)_num_coords) + ret+=_num_coords->getHeapMemorySize(); + if((const DataArrayInt *)_rev_num_coords) + ret+=_rev_num_coords->getHeapMemorySize(); + ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if((const MEDFileUMeshSplitL1*) *it) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + +MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); + if((const DataArrayDouble*)_coords) + ret->_coords=_coords->deepCpy(); + if((const DataArrayInt*)_fam_coords) + ret->_fam_coords=_fam_coords->deepCpy(); + if((const DataArrayInt*)_num_coords) + ret->_num_coords=_num_coords->deepCpy(); + if((const DataArrayInt*)_rev_num_coords) + ret->_rev_num_coords=_rev_num_coords->deepCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + ret->_ms[i]=(*it)->deepCpy(); + } + return ret.retn(); +} + bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const { if(!MEDFileMesh::isEqual(other,eps,what)) @@ -1428,7 +1554,6 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return false; } } - //std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; return true; } @@ -1666,6 +1791,52 @@ std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToM return ret; } +int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + int ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,val); + } + } + } + return ret; +} + +int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) +{ + int ret=std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMinValue(tmp); + ret=std::min(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=_fam_coords->getMinValue(tmp); + ret=std::min(ret,val); + } + } + } + return ret; +} + int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) { int lev=0; @@ -1832,8 +2003,7 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); ret->setCoords(c); - ret->incrRef(); - return ret; + return ret.retn(); } std::vector famIds=getFamiliesIds(fams); const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); @@ -1858,10 +2028,7 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve if(renum) return MEDFileUMeshSplitL1::Renumber(_num_coords,da); else - { - da->incrRef(); - return da; - } + return da.retn(); } else throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !"); @@ -1873,6 +2040,13 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve return l1->getFamilyPartArr(0,0,renum); } +/*! + * Returns a pointer to mesh at the specified level. + * + * \return a pointer to unstructured mesh that need to be managed by the caller. + * \warning the returned pointer has to be managed by the caller. + * \sa MEDFileUMesh::getGenMeshAtLevel + */ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception) { synchronizeTinyInfoOnLeaves(); @@ -1892,6 +2066,13 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu return l1->getWholeMesh(renum); } +/*! + * Returns a pointer to mesh at the specified level. + * + * \return a pointer to unstructured mesh that need to be managed by the caller. + * \warning the returned pointer has to be managed by the caller. + * \sa MEDFileUMesh::getMeshAtLevel + */ MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception) { return getMeshAtLevel(meshDimRelToMax,renum); @@ -2110,9 +2291,9 @@ void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt * newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); _fam_coords=newFam; } - nodesDuplicated=nodeIdsToDuplicate; nodeIdsToDuplicate->incrRef(); - cellsModified=cellsToModifyConn0; cellsToModifyConn0->incrRef(); - cellsNotModified=cellsToModifyConn1; cellsToModifyConn1->incrRef(); + nodesDuplicated=nodeIdsToDuplicate.retn(); + cellsModified=cellsToModifyConn0.retn(); + cellsNotModified=cellsToModifyConn1.retn(); } /*! @@ -2180,19 +2361,173 @@ bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode { MEDCouplingAutoRefCountObjectPtr renumCells=DataArrayInt::Aggregate(renumCellsSplited); MEDCouplingAutoRefCountObjectPtr o2nRenumCellRet=renumCells->buildPermArrPerLevel(); - o2nRenumCell=o2nRenumCellRet; o2nRenumCellRet->incrRef(); + o2nRenumCell=o2nRenumCellRet.retn(); } return ret; } -void MEDFileUMesh::addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception) +struct MEDLoaderAccVisit1 +{ + MEDLoaderAccVisit1():_new_nb_of_nodes(0) { } + int operator()(bool val) { return val?_new_nb_of_nodes++:-1; } + int _new_nb_of_nodes; +}; + +/*! + * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. + * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method. + * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. + * -1 values in returned array means that the corresponding old node is no more used. + * + * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched NULL pointer is returned and nothing + * is modified in \a this. + * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of + * set coordinates. + */ +DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception) +{ + const DataArrayDouble *coo=getCoords(); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); + int nbOfNodes=coo->getNumberOfTuples(); + std::vector nodeIdsInUse(nbOfNodes,false); + std::vector neLevs=getNonEmptyLevels(); + for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) + { + MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*lev); + m->computeNodeIdsAlg(nodeIdsInUse); + } + int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true); + if(nbrOfNodesInUse==nbOfNodes) + return 0; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1); + std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); + MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse); + MEDCouplingAutoRefCountObjectPtr newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end()); + MEDCouplingAutoRefCountObjectPtr newFamCoords; + if((const DataArrayInt *)_fam_coords) + newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + MEDCouplingAutoRefCountObjectPtr newNumCoords; + if((const DataArrayInt *)_num_coords) + newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _rev_num_coords=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) + { + if((MEDFileUMeshSplitL1*)*it) + (*it)->renumberNodesInConn(ret->begin()); + } + return ret.retn(); +} + +/*! + * This method is here only to add a group on node. + * MEDFileUMesh::setGroupsAtLevel with 1 in the first parameter. + * + * \param [in] ids node ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). + */ +void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception) { const DataArrayDouble *coords=_coords; if(!coords) - throw INTERP_KERNEL::Exception("addNodeGroup : no coords set !"); - DataArrayInt *sub=_fam_coords->selectByTupleIdSafe(&ids[0],&ids[0]+ids.size()); - std::set ssub(sub->getConstPointer(),sub->getConstPointer()+sub->getNumberOfTuples()); - + throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); + int nbOfNodes=coords->getNumberOfTuples(); + if(!((DataArrayInt *)_fam_coords)) + { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } + // + addGroupUnderground(ids,_fam_coords); +} + +void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception) +{ + std::vector levs=getNonEmptyLevelsExt(); + if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in "; + std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshDimRelToMaxExt==1) + { addNodeGroup(ids); return ; } + MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt); + DataArrayInt *fam=lev->getOrCreateAndGetFamilyField(); + addGroupUnderground(ids,fam); +} + +/*! + * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). + * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not NULL (no check of that will be performed) + */ +void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) +{ + if(!ids) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); + std::string grpName(ids->getName()); + if(grpName.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); + ids->checkStrictlyMonotonic(true); + famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr famArrTmp(famArr); + std::vector grpsNames=getGroupsNames(); + if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::list< MEDCouplingAutoRefCountObjectPtr > allFamIds=getAllNonNullFamilyIds(); + allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); + MEDCouplingAutoRefCountObjectPtr famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); + std::set diffFamIds=famIds->getDifferentValues(); + std::vector familyIds; + std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; + int maxVal=getTheMaxFamilyId()+1; + std::map families(_families); + std::map > groups(_groups); + std::vector fams; + bool created(false); + for(std::set::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++) + { + MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); + MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); + MEDCouplingAutoRefCountObjectPtr ids1=famArr->getIdsEqual(*famId); + MEDCouplingAutoRefCountObjectPtr ret0(ids1->buildSubstractionOptimized(ids2)); + if(ret0->empty()) + { + bool isFamPresent=false; + for(std::list< MEDCouplingAutoRefCountObjectPtr >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) + isFamPresent=(*itl)->presenceOfValue(*famId); + if(!isFamPresent) + { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp + else + { + familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ids2); std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,maxVal,created); + fams.push_back(locFamName); + if(existsFamily(*famId)) + { + std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v); + } + maxVal++; + } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal + } + else + { + familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 + familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 + std::string n2(FindOrCreateAndGiveFamilyWithId(families,maxVal+1,created)); fams.push_back(n2); + if(existsFamily(*famId)) + { + std::string n1(FindOrCreateAndGiveFamilyWithId(families,maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v); + } + maxVal+=2; + } + } + for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); + } + _families=families; + _groups=groups; + _groups[grpName]=fams; } void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception) @@ -2398,6 +2733,25 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL:: } } +std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAllNonNullFamilyIds() const +{ + std::list< MEDCouplingAutoRefCountObjectPtr > ret; + const DataArrayInt *da(_fam_coords); + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + const MEDFileUMeshSplitL1 *elt(*it); + if(elt) + { + da=elt->getFamilyField(); + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } + } + } + return ret; +} + void MEDFileUMesh::computeRevNum() const { if((const DataArrayInt *)_num_coords) @@ -2408,80 +2762,66 @@ void MEDFileUMesh::computeRevNum() const } } -MEDFileCMesh *MEDFileCMesh::New() +std::size_t MEDFileStructuredMesh::getHeapMemorySize() const { - return new MEDFileCMesh; + std::size_t ret=MEDFileMesh::getHeapMemorySize(); + if((const DataArrayInt*)_fam_nodes) + ret+=_fam_nodes->getHeapMemorySize(); + if((const DataArrayInt*)_num_nodes) + ret+=_num_nodes->getHeapMemorySize(); + if((const DataArrayInt*)_fam_cells) + ret+=_fam_cells->getHeapMemorySize(); + if((const DataArrayInt*)_num_cells) + ret+=_num_cells->getHeapMemorySize(); + if((const DataArrayInt*)_rev_num_nodes) + ret+=_rev_num_nodes->getHeapMemorySize(); + if((const DataArrayInt*)_rev_num_cells) + ret+=_rev_num_cells->getHeapMemorySize(); + return ret; } -MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception) +int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) { - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) + int ret=-std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_nodes) { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + int val=_fam_nodes->getMaxValue(tmp); + ret=std::max(ret,val); } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); - return new MEDFileCMesh(fid,ms.front().c_str(),dt,it); -} - -MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - return new MEDFileCMesh(fid,mName,dt,it); -} - -int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) -{ - if(!((const MEDCouplingCMesh*)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); - return _cmesh->getMeshDimension(); -} - -std::string MEDFileCMesh::simpleRepr() const -{ - return MEDFileMesh::simpleRepr(); + if((const DataArrayInt *)_fam_cells) + { + int val=_fam_cells->getMaxValue(tmp); + ret=std::max(ret,val); + } + return ret; } -std::string MEDFileCMesh::advancedRepr() const +int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) { - return simpleRepr(); + int ret=std::numeric_limits::max(),tmp=-1; + if((const DataArrayInt *)_fam_nodes) + { + int val=_fam_nodes->getMinValue(tmp); + ret=std::min(ret,val); + } + if((const DataArrayInt *)_fam_cells) + { + int val=_fam_cells->getMinValue(tmp); + ret=std::min(ret,val); + } + return ret; } -bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const { if(!MEDFileMesh::isEqual(other,eps,what)) return false; - const MEDFileCMesh *otherC=dynamic_cast(other); + const MEDFileStructuredMesh *otherC=dynamic_cast(other); if(!otherC) { - what="Mesh types differ ! This is cartesian and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const MEDCouplingCMesh *coo1=_cmesh; - const MEDCouplingCMesh *coo2=otherC->_cmesh; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of cartesian meshes ! One is defined and not other !"; + what="Mesh types differ ! This is structured and other is NOT !"; return false; } - if(coo1) - { - bool ret=coo1->isEqual(coo2,eps); - if(!ret) - { - what="cartesian meshes differ !"; - return false; - } - } const DataArrayInt *famc1=_fam_nodes; const DataArrayInt *famc2=otherC->_fam_nodes; if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) @@ -2549,10 +2889,9 @@ bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh return true; } -void MEDFileCMesh::clearNonDiscrAttributes() const +void MEDFileStructuredMesh::clearNonDiscrAttributes() const { MEDFileMesh::clearNonDiscrAttributes(); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh); const DataArrayInt *tmp=_fam_nodes; if(tmp) (const_cast(tmp))->setName(""); @@ -2567,61 +2906,234 @@ void MEDFileCMesh::clearNonDiscrAttributes() const (const_cast(tmp))->setName(""); } -MEDFileCMesh::MEDFileCMesh() -{ -} - -MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) -try - { - loadCMeshFromFile(fid,mName,dt,it); - } -catch(INTERP_KERNEL::Exception& e) - { - throw e; - } - -void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) { - MEDFileCMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); - if(meshType!=CARTESIAN) + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !"); + std::vector famIds=getFamiliesIds(fams); + if(meshDimRelToMaxExt==1) { - std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - loaderl2.loadAll(fid,mid,mName,dt,it); - MEDCouplingCMesh *mesh=loaderl2.getMesh(); - mesh->incrRef(); - _cmesh=mesh; - setName(loaderl2.getName()); - setDescription(loaderl2.getDescription()); - setIteration(loaderl2.getIteration()); - setOrder(loaderl2.getOrder()); - setTimeValue(loaderl2.getTime()); - setTimeUnit(loaderl2.getTimeUnit()); - MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups); - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) + if((const DataArrayInt *)_fam_nodes) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_nodes->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); + } + else { - _fam_nodes=DataArrayInt::New(); - _fam_nodes->alloc(nbOfElt,1); - MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); + if((const DataArrayInt *)_fam_cells) + { + MEDCouplingAutoRefCountObjectPtr da; + if(!famIds.empty()) + da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_cells->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); } - nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) +} + +void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); + const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); + if(meshDimRelToMaxExt==0) { - _num_nodes=DataArrayInt::New(); - _num_nodes->alloc(nbOfElt,1); - MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); + int nbCells=mesh->getNumberOfCells(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); + _fam_cells=famArr; } - int spaceDim=mesh->getSpaceDimension(); + else + { + int nbNodes=mesh->getNumberOfNodes(); + famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _fam_nodes=famArr; + } + if(famArr) + famArr->incrRef(); +} + +void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); + const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); + if(meshDimRelToMaxExt==0) + { + int nbCells=mesh->getNumberOfCells(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); + _num_cells=renumArr; + } + else + { + int nbNodes=mesh->getNumberOfNodes(); + renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _num_nodes=renumArr; + } + if(renumArr) + renumArr->incrRef(); +} + +const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !"); + if(meshDimRelToMaxExt==0) + return _fam_cells; + else + return _fam_nodes; +} + +const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !"); + if(meshDimRelToMaxExt==0) + return _num_cells; + else + return _num_nodes; +} + +const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); + if(meshDimRelToMaxExt==0) + { + if((const DataArrayInt *)_num_cells) + { + int pos; + int maxValue=_num_cells->getMaxValue(pos); + _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); + return _rev_num_cells; + } + else + throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !"); + } + else + { + if((const DataArrayInt *)_num_nodes) + { + int pos; + int maxValue=_num_nodes->getMaxValue(pos); + _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); + return _rev_num_nodes; + } + else + throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); + } +} + +std::vector MEDFileStructuredMesh::getNonEmptyLevels() const +{ + std::vector ret(1); + return ret; +} + +std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const +{ + std::vector ret(2); + ret[0]=1; + return ret; +} + +/*! + * no implementation here, it is not a bug, but intresically no polyhedra in \a this. + */ +bool MEDFileStructuredMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception) +{ + oldCode.clear(); newCode.clear(); o2nRenumCell=0; + return false; +} + +void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *arr=_fam_nodes; + if(arr) + arr->changeValue(oldId,newId); + arr=_fam_cells; + if(arr) + arr->changeValue(oldId,newId); +} + +void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception) +{ + if((const DataArrayInt*)_fam_nodes) + _fam_nodes=_fam_nodes->deepCpy(); + if((const DataArrayInt*)_num_nodes) + _num_nodes=_num_nodes->deepCpy(); + if((const DataArrayInt*)_fam_cells) + _fam_cells=_fam_cells->deepCpy(); + if((const DataArrayInt*)_num_cells) + _num_cells=_num_cells->deepCpy(); + if((const DataArrayInt*)_rev_num_nodes) + _rev_num_nodes=_rev_num_nodes->deepCpy(); + if((const DataArrayInt*)_rev_num_cells) + _rev_num_cells=_rev_num_cells->deepCpy(); +} + +/*! + * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh). + * + * \return a pointer to cartesian mesh that need to be managed by the caller. + * \warning the returned pointer has to be managed by the caller. + */ +MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception) +{ + if(renum) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); + if(meshDimRelToMax!=0) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); + const MEDCouplingStructuredMesh *m=getStructuredMesh(); + if(m) + m->incrRef(); + return const_cast(m); +} + +int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !"); + const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); + if(meshDimRelToMaxExt==0) + return cmesh->getNumberOfCells(); + else + return cmesh->getNumberOfNodes(); +} + +int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingStructuredMesh *cmesh=getStructuredMesh(); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); + return cmesh->getNumberOfNodes(); +} + +med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception) +{ med_geometry_type geoTypeReq=MED_NONE; - switch(spaceDim) + switch(meshDim) { case 3: geoTypeReq=MED_HEXA8; @@ -2636,8 +3148,37 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int geoTypeReq=MED_POINT1; break; default: - throw INTERP_KERNEL::Exception("Invalid spacedim detected for cartesian mesh ! Must be in (1,2,3) !"); + throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !"); + } + return geoTypeReq; +} + +void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +{ + setName(strm->getName()); + setDescription(strm->getDescription()); + setIteration(strm->getIteration()); + setOrder(strm->getOrder()); + setTimeValue(strm->getTime()); + setTimeUnit(strm->getTimeUnit()); + MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + _fam_nodes=DataArrayInt::New(); + _fam_nodes->alloc(nbOfElt,1); + MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()); + } + nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + _num_nodes=DataArrayInt::New(); + _num_nodes->alloc(nbOfElt,1); + MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()); } + int meshDim=getStructuredMesh()->getMeshDimension(); + med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); if(nbOfElt>0) { @@ -2654,14 +3195,160 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int } } -void MEDFileCMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) +void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception) +{ + int meshDim=getStructuredMesh()->getMeshDimension(); + med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim); + // + if((const DataArrayInt *)_fam_cells) + MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); + if((const DataArrayInt *)_fam_nodes) + MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); + if((const DataArrayInt *)_num_cells) + MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()); + if((const DataArrayInt *)_num_nodes) + MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()); + // + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); +} + +MEDFileCMesh *MEDFileCMesh::New() +{ + return new MEDFileCMesh; +} + +MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + std::vector ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); + return new MEDFileCMesh(fid,ms.front().c_str(),dt,it); +} + +MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + return new MEDFileCMesh(fid,mName,dt,it); +} + +std::size_t MEDFileCMesh::getHeapMemorySize() const +{ + std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize(); + if((const MEDCouplingCMesh *)_cmesh) + ret+=_cmesh->getHeapMemorySize(); + return ret; +} + +int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) +{ + if(!((const MEDCouplingCMesh*)_cmesh)) + throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); + return _cmesh->getMeshDimension(); +} + +std::string MEDFileCMesh::simpleRepr() const +{ + return MEDFileStructuredMesh::simpleRepr(); +} + +std::string MEDFileCMesh::advancedRepr() const +{ + return simpleRepr(); +} + +MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); + if((const MEDCouplingCMesh*)_cmesh) + ret->_cmesh=static_cast(_cmesh->deepCpy()); + ret->deepCpyAttributes(); + return ret.retn(); +} + +bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileStructuredMesh::isEqual(other,eps,what)) + return false; + const MEDFileCMesh *otherC=dynamic_cast(other); + if(!otherC) + { + what="Mesh types differ ! This is cartesian and other is NOT !"; + return false; + } + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const MEDCouplingCMesh *coo1=_cmesh; + const MEDCouplingCMesh *coo2=otherC->_cmesh; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) + { + what="Mismatch of cartesian meshes ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(coo2,eps); + if(!ret) + { + what="cartesian meshes differ !"; + return false; + } + } + return true; +} + +void MEDFileCMesh::clearNonDiscrAttributes() const +{ + MEDFileStructuredMesh::clearNonDiscrAttributes(); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented +} + +MEDFileCMesh::MEDFileCMesh() +{ +} + +MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +try + { + loadCMeshFromFile(fid,mName,dt,it); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) { - DataArrayInt *arr=_fam_nodes; - if(arr) - arr->changeValue(oldId,newId); - arr=_fam_cells; - if(arr) - arr->changeValue(oldId,newId); + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dtunit; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + if(meshType!=CARTESIAN) + { + std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileCMeshL2 loaderl2; + loaderl2.loadAll(fid,mid,mName,dt,it); + MEDCouplingCMesh *mesh=loaderl2.getMesh(); + mesh->incrRef(); + _cmesh=mesh; + loadStrMeshFromFile(&loaderl2,fid,mName,dt,it); } const MEDCouplingCMesh *MEDFileCMesh::getMesh() const @@ -2670,16 +3357,10 @@ const MEDCouplingCMesh *MEDFileCMesh::getMesh() const return _cmesh; } -MEDCouplingMesh *MEDFileCMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception) +const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const { - if(renum) - throw INTERP_KERNEL::Exception("MEDFileCMesh does not support renumbering ! To do it perform request of renum array directly !"); - if(meshDimRelToMax!=0) - throw INTERP_KERNEL::Exception("MEDFileCMesh does not support multi level for mesh 0 expected as input !"); - const MEDCouplingCMesh *m=getMesh(); - if(m) - m->incrRef(); - return const_cast(m); + synchronizeTinyInfoOnLeaves(); + return _cmesh; } void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception) @@ -2699,6 +3380,7 @@ void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); int spaceDim=_cmesh->getSpaceDimension(); + int meshDim=_cmesh->getMeshDimension(); INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); for(int i=0;igetNumberOfTuples(),da->getConstPointer()); } // - med_geometry_type geoTypeReq=MED_NONE; - switch(spaceDim) - { - case 3: - geoTypeReq=MED_HEXA8; - break; - case 2: - geoTypeReq=MED_QUAD4; - break; - case 1: - geoTypeReq=MED_SEG2; - break; - case 0: - geoTypeReq=MED_POINT1; - break; - default: - throw INTERP_KERNEL::Exception("Invalid spacedim detected for cartesian mesh ! Must be in (1,2,3) !"); - } - // - if((const DataArrayInt *)_fam_cells) - MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()); - if((const DataArrayInt *)_fam_nodes) - MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()); - // - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); -} - -int MEDFileCMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) -{ - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getSizeAtLevel : Only available for levels 0 or 1 !"); - if(!((const MEDCouplingCMesh *)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getSizeAtLevel : No cartesian mesh set !"); - if(meshDimRelToMaxExt==0) - return _cmesh->getNumberOfCells(); - else - return _cmesh->getNumberOfNodes(); + MEDFileStructuredMesh::writeStructuredLL(fid,maa); } void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const { const MEDCouplingCMesh *cmesh=_cmesh; + if(!cmesh) + return; (const_cast(cmesh))->setName(_name.c_str()); (const_cast(cmesh))->setDescription(_desc_name.c_str()); (const_cast(cmesh))->setTime(_time,_iteration,_order); (const_cast(cmesh))->setTimeUnit(_dt_unit.c_str()); } -int MEDFileCMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception) +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() { - const MEDCouplingCMesh *cmesh(_cmesh); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getNumberOfNodes : no cartesian mesh set !"); - return cmesh->getNumberOfNodes(); + return new MEDFileCurveLinearMesh; } -std::vector MEDFileCMesh::getNonEmptyLevels() const +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception) { - std::vector ret(1); - return ret; + std::vector ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); + return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it); } -std::vector MEDFileCMesh::getNonEmptyLevelsExt() const +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) { - std::vector ret(2); - ret[0]=1; + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + return new MEDFileCurveLinearMesh(fid,mName,dt,it); +} + +std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const +{ + std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize(); + if((const MEDCouplingCurveLinearMesh *)_clmesh) + ret+=_clmesh->getHeapMemorySize(); return ret; } -DataArrayInt *MEDFileCMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : Only available for levels 0 or 1 !"); - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); + if((const MEDCouplingCurveLinearMesh*)_clmesh) + ret->_clmesh=static_cast(_clmesh->deepCpy()); + ret->deepCpyAttributes(); + return ret.retn(); +} + +int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) +{ + if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); + return _clmesh->getMeshDimension(); +} + +std::string MEDFileCurveLinearMesh::simpleRepr() const +{ + return MEDFileStructuredMesh::simpleRepr(); +} + +std::string MEDFileCurveLinearMesh::advancedRepr() const +{ + return simpleRepr(); +} + +bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileStructuredMesh::isEqual(other,eps,what)) + return false; + const MEDFileCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - { - da->incrRef(); - return da; - } - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : no family array specified on nodes !"); + what="Mesh types differ ! This is curve linear and other is NOT !"; + return false; } - else + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const MEDCouplingCurveLinearMesh *coo1=_clmesh; + const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) { - if((const DataArrayInt *)_fam_cells) + what="Mismatch of curve linear meshes ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(coo2,eps); + if(!ret) { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - { - da->incrRef(); - return da; - } + what="curve linear meshes differ !"; + return false; } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : no family array specified on cells !"); } + return true; } -void MEDFileCMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) +void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); - if(famArr) - famArr->incrRef(); - if(meshDimRelToMaxExt==0) - _fam_cells=famArr; - else - _fam_nodes=famArr; + MEDFileStructuredMesh::clearNonDiscrAttributes(); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented } -void MEDFileCMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) +void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::setRenumFieldArr : Only available for levels 0 or 1 !"); - if(renumArr) - renumArr->incrRef(); - if(meshDimRelToMaxExt==0) - _num_cells=renumArr; - else - _num_nodes=renumArr; + const MEDCouplingCurveLinearMesh *clmesh=_clmesh; + if(!clmesh) + return; + (const_cast(clmesh))->setName(_name.c_str()); + (const_cast(clmesh))->setDescription(_desc_name.c_str()); + (const_cast(clmesh))->setTime(_time,_iteration,_order); + (const_cast(clmesh))->setTimeUnit(_dt_unit.c_str()); } -const DataArrayInt *MEDFileCMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _fam_cells; - else - return _fam_nodes; + synchronizeTinyInfoOnLeaves(); + return _clmesh; } -const DataArrayInt *MEDFileCMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception) { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - return _num_cells; - else - return _num_nodes; + dealWithTinyInfo(m); + if(m) + m->incrRef(); + _clmesh=m; } -const DataArrayInt *MEDFileCMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const { - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - { - if((const DataArrayInt *)_num_cells) - { - int pos; - int maxValue=_num_cells->getMaxValue(pos); - _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); - return _rev_num_cells; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !"); - } - else + synchronizeTinyInfoOnLeaves(); + return _clmesh; +} + +MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() +{ +} + +MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +try + { + loadCLMeshFromFile(fid,mName,dt,it); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +{ + INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); + MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); + MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); + int spaceDim=_clmesh->getSpaceDimension(); + int meshDim=_clmesh->getMeshDimension(); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + const DataArrayDouble *coords=_clmesh->getCoords(); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !"); + for(int i=0;igetMaxValue(pos); - _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); - return _rev_num_nodes; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); + std::string info(_clmesh->getCoords()->getInfoOnComponent(i)); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo } + MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit); + MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID); + std::vector nodeGridSt=_clmesh->getNodeGridStructure(); + MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]); + + MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()); + // + MEDFileStructuredMesh::writeStructuredLL(fid,maa); } -/*! - * no implementation here, it is not a bug, but intresically no polyhedra in \a this. - */ -bool MEDFileCMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception) +void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) { - oldCode.clear(); newCode.clear(); o2nRenumCell=0; - return false; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dtunit; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + if(meshType!=CURVE_LINEAR) + { + std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileCLMeshL2 loaderl2; + loaderl2.loadAll(fid,mid,mName,dt,it); + MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh(); + mesh->incrRef(); + _clmesh=mesh; + loadStrMeshFromFile(&loaderl2,fid,mName,dt,it); } MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() @@ -2931,6 +3631,26 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mN return new MEDFileMeshMultiTS(fileName,mName); } +MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshMultiTS::New(); + std::vector< MEDCouplingAutoRefCountObjectPtr > meshOneTs(_mesh_one_ts.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) + if((const MEDFileMesh *)*it) + meshOneTs[i]=(*it)->deepCpy(); + ret->_mesh_one_ts=meshOneTs; + return ret.retn(); +} + +std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const +{ + std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception) { if(_mesh_one_ts.empty()) @@ -3187,6 +3907,27 @@ catch(INTERP_KERNEL::Exception& e) { } +MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr > meshes(_meshes.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + if((const MEDFileMeshMultiTS *)*it) + meshes[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshes::New(); + ret->_meshes=meshes; + return ret.retn(); +} + +std::size_t MEDFileMeshes::getHeapMemorySize() const +{ + std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + if((const MEDFileMeshMultiTS*)*it) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + std::string MEDFileMeshes::simpleRepr() const { std::ostringstream oss; diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 02df40ac6..eb1e5bb37 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -26,6 +26,7 @@ #include "MEDFileUtilities.hxx" #include +#include namespace ParaMEDMEM { @@ -34,6 +35,9 @@ namespace ParaMEDMEM public: static MEDFileMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception) = 0; virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; virtual void clearNonDiscrAttributes() const; void setName(const char *name) { _name=name; } @@ -93,9 +97,14 @@ namespace ParaMEDMEM void changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); void changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception); + void changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception); int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); int getMinFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); + virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception) = 0; DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); std::vector getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception); std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); @@ -132,6 +141,8 @@ namespace ParaMEDMEM virtual void appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); virtual void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) = 0; static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); + static void ChangeAllGroupsContainingFamily(std::map >& groups, const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception); + static std::string FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created) throw(INTERP_KERNEL::Exception); static std::string CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid) throw(INTERP_KERNEL::Exception); static int PutInThirdComponentOfCodeOffset(std::vector& code, int strt) throw(INTERP_KERNEL::Exception); protected: @@ -156,10 +167,15 @@ namespace ParaMEDMEM static MEDFileUMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); static MEDFileUMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileUMesh *New(); + std::size_t getHeapMemorySize() const; + MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; void clearNonDiscrAttributes() const; ~MEDFileUMesh(); // + int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); int getMeshDimension() const throw(INTERP_KERNEL::Exception); int getSpaceDimension() const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; @@ -198,16 +214,18 @@ namespace ParaMEDMEM void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); - void addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception); + void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); + void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception); void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms) throw(INTERP_KERNEL::Exception); void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) throw(INTERP_KERNEL::Exception); void optimizeFamilies() throw(INTERP_KERNEL::Exception); - void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception); // tools + void duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception); bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception); + DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); private: void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); MEDFileUMesh(); @@ -220,6 +238,8 @@ namespace ParaMEDMEM void computeRevNum() const; void synchronizeTinyInfoOnLeaves() const; void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception); + std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const; + void addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); private: std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; MEDCouplingAutoRefCountObjectPtr _coords; @@ -228,48 +248,98 @@ namespace ParaMEDMEM mutable MEDCouplingAutoRefCountObjectPtr _rev_num_coords; }; - class MEDLOADER_EXPORT MEDFileCMesh : public MEDFileMesh + class MEDLOADER_EXPORT MEDFileStructuredMesh : public MEDFileMesh + { + friend class MEDFileMesh; + public: + std::size_t getHeapMemorySize() const; + int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; + DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); + void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); + const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + std::vector getNonEmptyLevels() const; + std::vector getNonEmptyLevelsExt() const; + MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception); + int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); + // tools + bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception); + protected: + void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception); + void deepCpyAttributes() throw(INTERP_KERNEL::Exception); + void loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); + void writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception); + virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0; + static med_geometry_type GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _fam_nodes; + MEDCouplingAutoRefCountObjectPtr _num_nodes; + MEDCouplingAutoRefCountObjectPtr _fam_cells; + MEDCouplingAutoRefCountObjectPtr _num_cells; + mutable MEDCouplingAutoRefCountObjectPtr _rev_num_nodes; + mutable MEDCouplingAutoRefCountObjectPtr _rev_num_cells; + }; + + class MEDLOADER_EXPORT MEDFileCMesh : public MEDFileStructuredMesh { friend class MEDFileMesh; public: static MEDFileCMesh *New(); static MEDFileCMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileCMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; int getMeshDimension() const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; void clearNonDiscrAttributes() const; const MEDCouplingCMesh *getMesh() const; - MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception); void setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception); - int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); - void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); - int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); - std::vector getNonEmptyLevels() const; - std::vector getNonEmptyLevelsExt() const; - const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - // tools - bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception); private: + const MEDCouplingStructuredMesh *getStructuredMesh() const; void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); MEDFileCMesh(); void synchronizeTinyInfoOnLeaves() const; MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); void loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); - void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception); private: MEDCouplingAutoRefCountObjectPtr _cmesh; - MEDCouplingAutoRefCountObjectPtr _fam_nodes; - MEDCouplingAutoRefCountObjectPtr _num_nodes; - MEDCouplingAutoRefCountObjectPtr _fam_cells; - MEDCouplingAutoRefCountObjectPtr _num_cells; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_nodes; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_cells; + }; + + class MEDLOADER_EXPORT MEDFileCurveLinearMesh : public MEDFileStructuredMesh + { + friend class MEDFileMesh; + public: + static MEDFileCurveLinearMesh *New(); + static MEDFileCurveLinearMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileCurveLinearMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + int getMeshDimension() const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + std::string advancedRepr() const; + void clearNonDiscrAttributes() const; + const MEDCouplingCurveLinearMesh *getMesh() const; + void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception); + private: + MEDFileCurveLinearMesh(); + MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); + const MEDCouplingStructuredMesh *getStructuredMesh() const; + void synchronizeTinyInfoOnLeaves() const; + void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception); + void loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception);//to imp + private: + MEDCouplingAutoRefCountObjectPtr _clmesh; }; class MEDLOADER_EXPORT MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable @@ -278,6 +348,8 @@ namespace ParaMEDMEM static MEDFileMeshMultiTS *New(); static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; const char *getName() const throw(INTERP_KERNEL::Exception); void setName(const char *newMeshName) throw(INTERP_KERNEL::Exception); bool changeNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception); @@ -301,6 +373,8 @@ namespace ParaMEDMEM public: static MEDFileMeshes *New(); static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception); + MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; std::string simpleRepr() const; void simpleReprWithoutHeader(std::ostream& oss) const; void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDFileMeshElt.hxx b/src/MEDLoader/MEDFileMeshElt.hxx index e8bda6629..fcce83e75 100644 --- a/src/MEDLoader/MEDFileMeshElt.hxx +++ b/src/MEDLoader/MEDFileMeshElt.hxx @@ -37,6 +37,7 @@ namespace ParaMEDMEM public: static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2); static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity); + std::size_t getHeapMemorySize() const { return 0; } int getDim() const; const DataArrayInt *getNodal() const { return _conn; } const DataArrayInt *getNodalIndex() const { return _conn_index; } diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index cfb86ad46..e6851db84 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -81,8 +81,22 @@ int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const char *mname, ParaMEDMEM: meshType=UNSTRUCTURED; break; case MED_STRUCTURED_MESH: - meshType=CARTESIAN; - break; + { + med_grid_type gt; + MEDmeshGridTypeRd(fid,mname,>); + switch(gt) + { + case MED_CARTESIAN_GRID: + meshType=CARTESIAN; + break; + case MED_CURVILINEAR_GRID: + meshType=CURVE_LINEAR; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); + } + break; + } default: throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); } @@ -135,8 +149,22 @@ std::vector MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, meshType=UNSTRUCTURED; break; case MED_STRUCTURED_MESH: - meshType=CARTESIAN; - break; + { + med_grid_type gt; + MEDmeshGridTypeRd(fid,mName,>); + switch(gt) + { + case MED_CARTESIAN_GRID: + meshType=CARTESIAN; + break; + case MED_CURVILINEAR_GRID: + meshType=CURVE_LINEAR; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); + } + break; + } default: throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); } @@ -334,7 +362,7 @@ void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, in med_grid_type gridtype; MEDmeshGridTypeRd(fid,mName,&gridtype); if(gridtype!=MED_CARTESIAN_GRID) - throw INTERP_KERNEL::Exception("Invalid cartesion mesh type ! Only Cartesian Grid supported ! Curvilinear grid will come soon !"); + throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !"); _cmesh=MEDCouplingCMesh::New(); for(int i=0;i infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); + if(meshType!=CURVE_LINEAR) + throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); + _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); + _iteration=dt; + _order=it; + // + _clmesh=MEDCouplingCurveLinearMesh::New(); + INTERP_KERNEL::AutoPtr stGrid=new int[Mdim]; + MEDmeshGridStructRd(fid,mName,dt,it,stGrid); + _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbNodes=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf); + MEDCouplingAutoRefCountObjectPtr da=DataArrayDouble::New(); + da->alloc(nbNodes,infosOnComp.size()); + da->setInfoOnComponents(infosOnComp); + MEDmeshNodeCoordinateRd(fid,mName,dt,it,MED_FULL_INTERLACE,da->getPointer()); + _clmesh->setCoords(da); +} + MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0) { } @@ -378,27 +436,20 @@ MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const if((MEDCouplingUMesh *)_m==0) { updateTime(); - MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy(); - _m=ret; + _m=static_cast(_st->_m_by_types->deepCpy()); _m->renumberCells(_st->_num->getConstPointer(),true); - ret->incrRef(); - return ret; + return _m.retn(); } else { if(_mpt_time==_st->_m_by_types->getTimeOfThis() && _num_time==_st->_num->getTimeOfThis()) - { - _m->incrRef(); - return _m; - } + return _m.retn(); else { updateTime(); - MEDCouplingUMesh *ret=(MEDCouplingUMesh *)_st->_m_by_types->deepCpy(); - _m=ret; + _m=static_cast(_st->_m_by_types->deepCpy()); _m->renumberCells(_st->_num->getConstPointer(),true); - ret->incrRef(); - return ret; + return _m.retn(); } } } @@ -414,6 +465,10 @@ void MEDFileUMeshPermCompute::updateTime() const _num_time=_st->_num->getTimeOfThis(); } +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_rev_num(other._rev_num),_m(this) +{ +} + MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id):_m(this) { const std::vector< MEDCouplingAutoRefCountObjectPtr >& v=l2.getLev(id); @@ -463,6 +518,38 @@ MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m( assignMesh(m,newOrOld); } +std::size_t MEDFileUMeshSplitL1::getHeapMemorySize() const +{ + std::size_t ret=0; + if((const MEDCouplingUMesh *)_m_by_types) + { + ret+=_m_by_types->getHeapMemorySize(); + if((const DataArrayDouble *)_m_by_types->getCoords()) + ret-=_m_by_types->getCoords()->getHeapMemorySize(); + } + if((const DataArrayInt*)_fam) + ret+=_fam->getHeapMemorySize(); + if((const DataArrayInt*)_num) + ret+=_num->getHeapMemorySize(); + if((const DataArrayInt*)_rev_num) + ret+=_rev_num->getHeapMemorySize(); + return ret; +} + +MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMeshSplitL1(*this); + if((const MEDCouplingUMesh*)_m_by_types) + ret->_m_by_types=static_cast(_m_by_types->deepCpy()); + if((const DataArrayInt *)_fam) + ret->_fam=_fam->deepCpy(); + if((const DataArrayInt *)_num) + ret->_num=_num->deepCpy(); + if((const DataArrayInt *)_rev_num) + ret->_rev_num=_rev_num->deepCpy(); + return ret.retn(); +} + bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const { const MEDCouplingUMesh *m1=_m_by_types; @@ -611,8 +698,7 @@ DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int MEDCouplingAutoRefCountObjectPtr da=_fam->getIdsEqualList(idsBg,idsEnd); if(renum) return renumIfNeededArr(da); - da->incrRef(); - return da; + return da.retn(); } MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const @@ -622,8 +708,19 @@ MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const tmp=_m; else tmp=_m_by_types; - tmp->incrRef(); - return tmp; + return tmp.retn(); +} + +DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField() throw(INTERP_KERNEL::Exception) +{ + if((DataArrayInt *)_fam) + return _fam; + MEDCouplingUMesh *m(_m_by_types); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField : impossible to create a family field array because no mesh specified on this level !"); + int nbOfTuples=m->getNumberOfCells(); + _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero(); + return _fam; } const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const @@ -686,6 +783,14 @@ void MEDFileUMeshSplitL1::write(med_idt fid, const char *mName, int mdim) const } } +void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception) +{ + MEDCouplingUMesh *m(_m_by_types); + if(!m) + return; + m->renumberNodesInConn(newNodeNumbersO2N); +} + void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) { DataArrayInt *arr=_fam; diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx index 263f77d41..07306af54 100644 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ b/src/MEDLoader/MEDFileMeshLL.hxx @@ -26,6 +26,7 @@ #include "MEDCouplingUMesh.hxx" #include "MEDCouplingCMesh.hxx" +#include "MEDCouplingCurveLinearMesh.hxx" #include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "med.h" @@ -38,6 +39,7 @@ namespace ParaMEDMEM { public: MEDFileMeshL2(); + std::size_t getHeapMemorySize() const { return 0; } const char *getName() const { return _name.getReprForWrite(); } const char *getDescription() const { return _description.getReprForWrite(); } const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); } @@ -83,7 +85,11 @@ namespace ParaMEDMEM MEDCouplingAutoRefCountObjectPtr _num_coords; }; - class MEDFileCMeshL2 : public MEDFileMeshL2 + class MEDFileStrMeshL2 : public MEDFileMeshL2 + { + }; + + class MEDFileCMeshL2 : public MEDFileStrMeshL2 { public: MEDFileCMeshL2(); @@ -94,6 +100,16 @@ namespace ParaMEDMEM private: MEDCouplingAutoRefCountObjectPtr _cmesh; }; + + class MEDFileCLMeshL2 : public MEDFileStrMeshL2 + { + public: + MEDFileCLMeshL2(); + void loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); + MEDCouplingCurveLinearMesh *getMesh() { return _clmesh; } + private: + MEDCouplingAutoRefCountObjectPtr _clmesh; + }; class MEDFileMesh; class MEDFileUMeshSplitL1; @@ -116,9 +132,12 @@ namespace ParaMEDMEM { friend class MEDFileUMeshPermCompute; public: + MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other); MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id); MEDFileUMeshSplitL1(MEDCouplingUMesh *m); MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld); + std::size_t getHeapMemorySize() const; + MEDFileUMeshSplitL1 *deepCpy() const; bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const; void clearNonDiscrAttributes() const; void synchronizeTinyInfo(const MEDFileMesh& master) const; @@ -131,6 +150,7 @@ namespace ParaMEDMEM MEDCouplingUMesh *getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const; DataArrayInt *getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const; MEDCouplingUMesh *getWholeMesh(bool renum) const; + DataArrayInt *getOrCreateAndGetFamilyField() throw(INTERP_KERNEL::Exception); const DataArrayInt *getFamilyField() const; const DataArrayInt *getNumberField() const; const DataArrayInt *getRevNumberField() const; @@ -143,6 +163,8 @@ namespace ParaMEDMEM void setRenumArr(DataArrayInt *renumArr); void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception); // + void renumberNodesInConn(const int *newNodeNumbersO2N) throw(INTERP_KERNEL::Exception); + // static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp); static std::vector GetNewFamiliesNumber(int nb, const std::map& families); static void TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, diff --git a/src/MEDLoader/SauvMedConvertor.cxx b/src/MEDLoader/SauvMedConvertor.cxx index 75e1d0c13..bf2c9d1d0 100644 --- a/src/MEDLoader/SauvMedConvertor.cxx +++ b/src/MEDLoader/SauvMedConvertor.cxx @@ -1118,8 +1118,7 @@ ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS() medData->setMeshes( meshes ); if ( fields ) medData->setFields( fields ); - medData->incrRef(); - return medData; + return medData.retn(); } //================================================================================ diff --git a/src/MEDLoader/SauvReader.cxx b/src/MEDLoader/SauvReader.cxx index 720d34b65..5b17dcdf7 100644 --- a/src/MEDLoader/SauvReader.cxx +++ b/src/MEDLoader/SauvReader.cxx @@ -55,8 +55,7 @@ SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception if ( parser->open() ) { SauvReader* reader = new SauvReader; - reader->_fileReader = parser; - parser->incrRef(); + reader->_fileReader = parser.retn(); return reader; } @@ -65,8 +64,7 @@ SauvReader* SauvReader::New(const char *fileName) throw(INTERP_KERNEL::Exception if ( parser->open() ) { SauvReader* reader = new SauvReader; - reader->_fileReader = parser; - parser->incrRef(); + reader->_fileReader = parser.retn(); return reader; } diff --git a/src/MEDLoader/SauvReader.hxx b/src/MEDLoader/SauvReader.hxx index eaf49c7a1..0b9b6989e 100644 --- a/src/MEDLoader/SauvReader.hxx +++ b/src/MEDLoader/SauvReader.hxx @@ -51,6 +51,7 @@ class MEDLOADER_EXPORT SauvReader : public ParaMEDMEM::RefCountObject ~SauvReader(); private: + std::size_t getHeapMemorySize() const { return 0; } void readRecord2(); void readRecord4(); diff --git a/src/MEDLoader/SauvUtilities.hxx b/src/MEDLoader/SauvUtilities.hxx index 40c364228..107552b8f 100644 --- a/src/MEDLoader/SauvUtilities.hxx +++ b/src/MEDLoader/SauvUtilities.hxx @@ -109,7 +109,8 @@ namespace SauvUtilities virtual float getFloat() const = 0; virtual double getDouble() const = 0; virtual std::string getName() const = 0; - + protected: + std::size_t getHeapMemorySize() const { return 0; } protected: std::string _fileName, _curLocale; int _iRead, _nbToRead; diff --git a/src/MEDLoader/SauvWriter.hxx b/src/MEDLoader/SauvWriter.hxx index 7ba8a6a76..e27c54551 100644 --- a/src/MEDLoader/SauvWriter.hxx +++ b/src/MEDLoader/SauvWriter.hxx @@ -51,7 +51,7 @@ namespace ParaMEDMEM void write(const char* fileName); private: - + std::size_t getHeapMemorySize() const { return 0; } /*! * \brief Class representing a GIBI sub-mesh (described in the pile 1 of the SAUVE file). * It stands for a named med sub-mesh (family, etc) and contains either cell IDs or other sub-meshes. diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i index f99f6635b..84736406e 100644 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ b/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -55,6 +55,8 @@ using namespace ParaMEDMEM; %newobject MEDLoader::ReadFieldGauss; %newobject MEDLoader::ReadFieldGaussNE; %newobject ParaMEDMEM::MEDFileMesh::New; +%newobject ParaMEDMEM::MEDFileMesh::deepCpy; +%newobject ParaMEDMEM::MEDFileMesh::shallowCpy; %newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel; %newobject ParaMEDMEM::MEDFileMesh::getGroupArr; %newobject ParaMEDMEM::MEDFileMesh::getGroupsArr; @@ -76,21 +78,27 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; +%newobject ParaMEDMEM::MEDFileUMesh::zipCoords; %newobject ParaMEDMEM::MEDFileCMesh::New; +%newobject ParaMEDMEM::MEDFileCurveLinearMesh::New; %newobject ParaMEDMEM::MEDFileMeshMultiTS::New; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::deepCpy; %newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep; %newobject ParaMEDMEM::MEDFileMeshes::New; +%newobject ParaMEDMEM::MEDFileMeshes::deepCpy; %newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos; %newobject ParaMEDMEM::MEDFileMeshes::getMeshWithName; %newobject ParaMEDMEM::MEDFileMeshes::__getitem__; %newobject ParaMEDMEM::MEDFileMeshes::__iter__; %newobject ParaMEDMEM::MEDFileFields::New; +%newobject ParaMEDMEM::MEDFileFields::deepCpy; %newobject ParaMEDMEM::MEDFileFields::getFieldWithName; %newobject ParaMEDMEM::MEDFileFields::getFieldAtPos; %newobject ParaMEDMEM::MEDFileFields::__getitem__; %newobject ParaMEDMEM::MEDFileFields::__iter__; %newobject ParaMEDMEM::MEDFileFieldMultiTS::New; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::deepCpy; %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStepAtPos; %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStep; %newobject ParaMEDMEM::MEDFileFieldMultiTS::getTimeStepGivenTime; @@ -102,6 +110,7 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevelOld; %newobject ParaMEDMEM::MEDFileFieldMultiTS::getUndergroundDataArray; %newobject ParaMEDMEM::MEDFileField1TS::New; +%newobject ParaMEDMEM::MEDFileField1TS::deepCpy; %newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevel; %newobject ParaMEDMEM::MEDFileField1TS::getFieldAtTopLevel; %newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel; @@ -109,6 +118,7 @@ using namespace ParaMEDMEM; %newobject ParaMEDMEM::MEDFileField1TS::getUndergroundDataArray; %newobject ParaMEDMEM::MEDFileData::New; +%newobject ParaMEDMEM::MEDFileData::deepCpy; %newobject ParaMEDMEM::MEDFileData::getMeshes; %newobject ParaMEDMEM::MEDFileData::getFields; @@ -329,6 +339,8 @@ namespace ParaMEDMEM public: static MEDFileMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1); + virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); virtual void clearNonDiscrAttributes() const; void setName(const char *name); const char *getName(); @@ -378,11 +390,16 @@ namespace ParaMEDMEM void changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); void changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception); + void changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception); void setFamilyInfo(const std::map& info); void setGroupInfo(const std::map >&info); int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); int getMinFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); + virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); std::vector getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception); std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); @@ -569,13 +586,15 @@ namespace ParaMEDMEM void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); - void addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception); + void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); + void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); void setMeshAtLevelGen(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception); void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms) throw(INTERP_KERNEL::Exception); void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) throw(INTERP_KERNEL::Exception); void optimizeFamilies() throw(INTERP_KERNEL::Exception); + DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); %extend { MEDFileUMesh(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception) @@ -629,7 +648,11 @@ namespace ParaMEDMEM } }; - class MEDFileCMesh : public MEDFileMesh + class MEDFileStructuredMesh : public MEDFileMesh + { + }; + + class MEDFileCMesh : public MEDFileStructuredMesh { public: static MEDFileCMesh *New(); @@ -663,12 +686,47 @@ namespace ParaMEDMEM } }; + class MEDFileCurveLinearMesh : public MEDFileStructuredMesh + { + public: + static MEDFileCurveLinearMesh *New(); + static MEDFileCurveLinearMesh *New(const char *fileName) throw(INTERP_KERNEL::Exception); + static MEDFileCurveLinearMesh *New(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); + void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileCurveLinearMesh() + { + return MEDFileCurveLinearMesh::New(); + } + + MEDFileCurveLinearMesh(const char *fileName) throw(INTERP_KERNEL::Exception) + { + return MEDFileCurveLinearMesh::New(fileName); + } + + MEDFileCurveLinearMesh(const char *fileName, const char *mName, int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception) + { + return MEDFileCurveLinearMesh::New(fileName,mName,dt,it); + } + + PyObject *getMesh() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCurveLinearMesh *tmp=self->getMesh(); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh, SWIG_POINTER_OWN | 0 ); + } + } + }; + class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable { public: static MEDFileMeshMultiTS *New(); static MEDFileMeshMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileMeshMultiTS *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); const char *getName() const throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); @@ -726,6 +784,7 @@ namespace ParaMEDMEM public: static MEDFileMeshes *New(); static MEDFileMeshes *New(const char *fileName) throw(INTERP_KERNEL::Exception); + MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); std::vector getMeshesNames() const throw(INTERP_KERNEL::Exception); @@ -823,6 +882,7 @@ namespace ParaMEDMEM { public: void shallowCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); + void deepCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); std::vector getPfls() const throw(INTERP_KERNEL::Exception); std::vector getLocs() const throw(INTERP_KERNEL::Exception); bool existsPfl(const char *pflName) const throw(INTERP_KERNEL::Exception); @@ -940,6 +1000,7 @@ namespace ParaMEDMEM void setProfileNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); void setLocNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); + MEDFileField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); // int getDimension() const throw(INTERP_KERNEL::Exception); int getIteration() const throw(INTERP_KERNEL::Exception); @@ -1165,6 +1226,7 @@ namespace ParaMEDMEM static MEDFileFieldMultiTS *New() throw(INTERP_KERNEL::Exception); static MEDFileFieldMultiTS *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); + MEDFileFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); // MEDFileField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); MEDFileField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); @@ -1207,9 +1269,14 @@ namespace ParaMEDMEM } std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } + { + return self->simpleRepr(); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfTS(); + } MEDFileField1TS *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) { @@ -1545,6 +1612,7 @@ namespace ParaMEDMEM public: static MEDFileFields *New() throw(INTERP_KERNEL::Exception); static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); + MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception); void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; std::vector getFieldsNames() const throw(INTERP_KERNEL::Exception); @@ -1611,6 +1679,7 @@ namespace ParaMEDMEM public: static MEDFileData *New(const char *fileName) throw(INTERP_KERNEL::Exception); static MEDFileData *New(); + MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception); void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); int getNumberOfFields() const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index 194def721..3f66653fd 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -164,7 +164,9 @@ class MEDLoaderTest(unittest.TestCase): t=mm.getGroupArr(0,"GrpOnAllCell") self.assertTrue(t.getValues()==range(5)) # - mm.write(outFileName,2); + mmCpy=mm.deepCpy() + self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) ; del mm + mmCpy.write(outFileName,2); # mm=MEDFileMesh.New(outFileName) mbis=mm.getMeshAtLevel(0) @@ -384,6 +386,7 @@ class MEDLoaderTest(unittest.TestCase): mm.write("Pyfile17_bis.med",2) ff=MEDFileFieldMultiTS("Pyfile17.med") tsExpected=[[1,2],[3,4],[5,6]] + self.assertEqual(3,len(ff)) for pos,f1ts in enumerate(ff): self.assertEqual(tsExpected[pos],f1ts.getTime()[:2]) self.assertEqual(type(f1ts),MEDFileField1TS) @@ -642,6 +645,7 @@ class MEDLoaderTest(unittest.TestCase): # ff1.setFieldProfile(f1,mm1,0,da) ff1.changePflsNames([(["sup1_NORM_QUAD4"],"ForV650")]) + ff1=ff1.deepCpy() ff1.write(fname,0) # vals,pfl=ff1.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") @@ -649,6 +653,8 @@ class MEDLoaderTest(unittest.TestCase): self.assertTrue(vals.isEqual(d,1e-14)) # ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + ff3=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + ff2.deepCpyGlobs(ff3) sbt=ff2.getFieldSplitedByType2() self.assertEqual(3,sbt[0][0])#TRI3 self.assertEqual(0,sbt[0][1][0][0])#CELL For TRI3 @@ -679,6 +685,7 @@ class MEDLoaderTest(unittest.TestCase): ff1.appendFieldProfile(f1,mm1,0,da) f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; ff1.appendFieldProfile(f1,mm1,0,da) + ff1=ff1.deepCpy() ff1.write(fname,0) # vals,pfl=ff1.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") @@ -912,6 +919,7 @@ class MEDLoaderTest(unittest.TestCase): ff1.appendFieldProfile(f1,mm1,0,da) ffs.resize(1) ffs.setFieldAtPos(0,ff1) + ffs=ffs.deepCpy() ffs.write(fname,0) # ffsr=MEDFileFields.New(fname) @@ -1582,6 +1590,420 @@ class MEDLoaderTest(unittest.TestCase): f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) pass + + # Testing profile on nodes when the profile is identity but not on all nodes. + def testMEDFieldPflOnNode1(self): + fname="Pyfile51.med" + coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) + m0=MEDCouplingUMesh("Mesh",2) + m0.allocateCells(5) + m0.insertNextCell(NORM_TRI3,[1,4,2]) + m0.insertNextCell(NORM_TRI3,[4,5,2]) + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) + m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) + m0.finishInsertingCells() + m0.setCoords(coo) + m1=MEDCouplingUMesh(m0.getName(),1) + m1.allocateCells(9) + conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] + for i in xrange(9): + m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) + pass + m1.finishInsertingCells() + m1.setCoords(coo) + # + m=MEDFileUMesh() + m.setMeshAtLevel(0,m0) + m.setMeshAtLevel(-1,m1) + # + dt=3 ; it=2 ; tim=4.5 + fieldNode0=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) + fieldNode0.setName("fieldNode0") + fieldNode0.setTime(tim,dt,it) + pfl0=DataArrayInt([0,1,2,3,4]) ; pfl0.setName("PflIdentity0") # important to keep like that + arr=DataArrayDouble([10,11,12,13,14]) + fieldNode0.setArray(arr) + f0=MEDFileField1TS() + f0.setFieldProfile(fieldNode0,m,0,pfl0) + m.write(fname,2) ; f0.write(fname,0) + fieldNode1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) + fieldNode1.setName("fieldNode1") + fieldNode1.setTime(tim,dt,it) + pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") + arr1=DataArrayDouble([20,21,22,23,24,25,26]) + fieldNode1.setArray(arr1) + f1=MEDFileField1TS() + f1.setFieldProfile(fieldNode1,m,-1,pfl1) + f1.write(fname,0) + del m,f0,m0,m1,f1 + ## Reading from file + m=MEDFileMesh.New(fname) + m0=m.getMeshAtLevel(0) + m00=m0.deepCpy() ; m00=m00[[0,2]] ; m00.setName(m.getName()) ; m00.zipCoords() + fieldNode0.setMesh(m00) + f0=MEDFileField1TS.New(fname,fieldNode0.getName(),dt,it) + ff0_1=f0.getFieldOnMeshAtLevel(ON_NODES,m0) + ff0_1.checkCoherency() + self.assertTrue(ff0_1.isEqual(fieldNode0,1e-12,1e-12)) + ff0_2=f0.getFieldAtLevel(ON_NODES,0) + ff0_2.checkCoherency() + self.assertTrue(ff0_2.isEqual(fieldNode0,1e-12,1e-12)) + ff0_3=f0.getFieldOnMeshAtLevel(ON_NODES,0,m) + ff0_3.checkCoherency() + self.assertTrue(ff0_3.isEqual(fieldNode0,1e-12,1e-12)) + ff0_4=MEDLoader.ReadFieldNode(fname,m.getName(),0,fieldNode0.getName(),dt,it) + ff0_4.checkCoherency() + self.assertTrue(ff0_4.isEqual(fieldNode0,1e-12,1e-12)) + f1=MEDFileField1TS.New(fname,fieldNode1.getName(),dt,it) + m1=m.getMeshAtLevel(-1) + m10=m1.deepCpy() ; m10=m10[[0,1,2,3,4,5,6,7]] ; m10.setName(m.getName()) ; m10.zipCoords() + fieldNode1.setMesh(m10) + ff1_1=f1.getFieldOnMeshAtLevel(ON_NODES,m1) + ff1_1.checkCoherency() + self.assertTrue(ff1_1.isEqual(fieldNode1,1e-12,1e-12)) + ff1_2=f1.getFieldAtLevel(ON_NODES,-1) + ff1_2.checkCoherency() + self.assertTrue(ff1_2.isEqual(fieldNode1,1e-12,1e-12)) + ff1_3=f1.getFieldOnMeshAtLevel(ON_NODES,-1,m) + ff1_3.checkCoherency() + self.assertTrue(ff1_3.isEqual(fieldNode1,1e-12,1e-12)) + ff1_4=MEDLoader.ReadFieldNode(fname,m.getName(),-1,fieldNode1.getName(),dt,it) + ff1_4.checkCoherency() + self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,m0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_NODES,0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,0,m) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + arr_r,pfl1_r=f1.getFieldWithProfile(ON_NODES,-1,m) + arr_r.setName(fieldNode1.getArray().getName()) + self.assertTrue(arr_r.isEqual(fieldNode1.getArray(),1e-12)) + pfl1_r.setName(pfl1.getName()) + self.assertTrue(pfl1_r.isEqual(pfl1)) + pass + + # Testing profile on nodes when the profile is identity but not on all nodes. + def testMEDFieldPflOnCell1(self): + fname="Pyfile52.med" + coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) + m0=MEDCouplingUMesh("Mesh",2) + m0.allocateCells(5) + m0.insertNextCell(NORM_TRI3,[1,4,2]) + m0.insertNextCell(NORM_TRI3,[4,5,2]) + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) + m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) + m0.finishInsertingCells() + m0.setCoords(coo) + m1=MEDCouplingUMesh(m0.getName(),1) + m1.allocateCells(9) + conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] + for i in xrange(9): + m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) + pass + m1.finishInsertingCells() + m1.setCoords(coo) + # + m=MEDFileUMesh() + m.setMeshAtLevel(0,m0) + m.setMeshAtLevel(-1,m1) + # + dt=3 ; it=2 ; tim=4.5 + fieldCell0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + fieldCell0.setName("fieldCell0") + fieldCell0.setTime(tim,dt,it) + pfl0=DataArrayInt([0,1,2]) ; pfl0.setName("PflIdentity0") # important to keep like that + arr=DataArrayDouble([10,11,12]) + fieldCell0.setArray(arr) + f0=MEDFileField1TS() + f0.setFieldProfile(fieldCell0,m,0,pfl0) + m.write(fname,2) ; f0.write(fname,0) + fieldCell1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + fieldCell1.setName("fieldCell1") + fieldCell1.setTime(tim,dt,it) + pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") + arr1=DataArrayDouble([20,21,22,23,24,25,26]) + fieldCell1.setArray(arr1) + f1=MEDFileField1TS() + f1.setFieldProfile(fieldCell1,m,-1,pfl1) + f1.write(fname,0) + del m,f0,m0,m1,f1 + ## Reading from file + m=MEDFileMesh.New(fname) + m0=m.getMeshAtLevel(0) + m00=m0.deepCpy() ; m00=m00[pfl0] ; m00.setName(m.getName()) + fieldCell0.setMesh(m00) + f0=MEDFileField1TS.New(fname,fieldCell0.getName(),dt,it) + ff0_1=f0.getFieldOnMeshAtLevel(ON_CELLS,m0) + ff0_1.checkCoherency() + self.assertTrue(ff0_1.isEqual(fieldCell0,1e-12,1e-12)) + ff0_2=f0.getFieldAtLevel(ON_CELLS,0) + ff0_2.checkCoherency() + self.assertTrue(ff0_2.isEqual(fieldCell0,1e-12,1e-12)) + ff0_3=f0.getFieldOnMeshAtLevel(ON_CELLS,0,m) + ff0_3.checkCoherency() + self.assertTrue(ff0_3.isEqual(fieldCell0,1e-12,1e-12)) + ff0_4=MEDLoader.ReadFieldCell(fname,m.getName(),0,fieldCell0.getName(),dt,it) + ff0_4.checkCoherency() + self.assertTrue(ff0_4.isEqual(fieldCell0,1e-12,1e-12)) + f1=MEDFileField1TS.New(fname,fieldCell1.getName(),dt,it) + m1=m.getMeshAtLevel(-1) + m10=m1.deepCpy() ; m10=m10[pfl1] ; m10.setName(m.getName()) + fieldCell1.setMesh(m10) + ff1_1=f1.getFieldOnMeshAtLevel(ON_CELLS,m1) + ff1_1.checkCoherency() + self.assertTrue(ff1_1.isEqual(fieldCell1,1e-12,1e-12)) + ff1_2=f1.getFieldAtLevel(ON_CELLS,-1) + ff1_2.checkCoherency() + self.assertTrue(ff1_2.isEqual(fieldCell1,1e-12,1e-12)) + ff1_3=f1.getFieldOnMeshAtLevel(ON_CELLS,-1,m) + ff1_3.checkCoherency() + self.assertTrue(ff1_3.isEqual(fieldCell1,1e-12,1e-12)) + ff1_4=MEDLoader.ReadFieldCell(fname,m.getName(),-1,fieldCell1.getName(),dt,it) + ff1_4.checkCoherency() + self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,m0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_CELLS,0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,0,m) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + arr_r,pfl1_r=f1.getFieldWithProfile(ON_CELLS,-1,m) + arr_r.setName(fieldCell1.getArray().getName()) + self.assertTrue(arr_r.isEqual(fieldCell1.getArray(),1e-12)) + pfl1_r.setName(pfl1.getName()) + self.assertTrue(pfl1_r.isEqual(pfl1)) + pass + + def testMEDFileUMeshZipCoords1(self): + m=MEDFileUMesh() + coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo) + famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo) + da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da) + da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da) + da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da) + o2n=m.zipCoords() + self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1]))) + self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11]))) + self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12]))) + self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1]))) + self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15]))) + self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2]))) + self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6]))) + self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6]))) + pass + + def testMEDUMeshAddNodeGroup1(self): + fname="Pyfile53.med" + m=MEDFileUMesh() + coo=DataArrayDouble(39) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + # + mm=m.deepCpy() + famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(1,famCoo) + da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(0,da0) + da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) + da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) + mm.setFamilyId("MyFam",2) + mm.setFamilyId("MyOtherFam",3) + mm.setFamilyId("MyOther-1",-1) + mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) + mm.setFamiliesOnGroup("grpA",["MyOther-1"]) + # + daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") + mm.addNodeGroup(daTest) + self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + mm.write(fname,2) + mm=MEDFileMesh.New(fname) + self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + pass + + def testMEDUMeshAddGroup1(self): + fname="Pyfile54.med" + m=MEDFileUMesh() + coo=DataArrayDouble(9) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) + for i in xrange(7): + m0.insertNextCell(NORM_TRI3,[1,2,1]) + pass + for i in xrange(4): + m0.insertNextCell(NORM_QUAD4,[1,1,2,0]) + pass + for i in xrange(2): + m0.insertNextCell(NORM_POLYGON,[0,0,1,1,2,2]) + pass + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + # + mm=m.deepCpy() + famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(0,famCoo) + da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(1,da0) + da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) + da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) + mm.setFamilyId("MyFam",2) + mm.setFamilyId("MyOtherFam",3) + mm.setFamilyId("MyOther-1",-1) + mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) + mm.setFamiliesOnGroup("grpA",["MyOther-1"]) + # + daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") + mm.addGroup(0,daTest) + self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + mm.write(fname,2) + mm=MEDFileMesh.New(fname) + self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + pass + + def testHeapMem1(self): + import platform + ver=platform.python_version_tuple() + if int(ver[0])!=2 or int(ver[1])<7: + return + m=MEDCouplingCMesh() + arr=DataArrayDouble(10,1) ; arr.iota(0) + m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName("mm") + f=m.getMeasureField(ON_CELLS) + self.assertIn(m.getHeapMemorySize(),xrange(3552-100,3552+100)) + self.assertIn(f.getHeapMemorySize(),xrange(4215-100,4215+100)) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + self.assertIn(mm.getHeapMemorySize(),xrange(3889-100,3889+100)) + ff=MEDFileField1TS() + ff.setFieldNoProfileSBT(f) + self.assertIn(ff.getHeapMemorySize(),xrange(711-10,711+10)) + # + fff=MEDFileFieldMultiTS() + fff.appendFieldNoProfileSBT(f) + self.assertIn(fff.getHeapMemorySize(),xrange(743-10,743+10)) + self.assertIn(fff[-1,-1].getHeapMemorySize(),xrange(711-10,711+10)) + f.setTime(1.,0,-1) + fff.appendFieldNoProfileSBT(f) + self.assertIn(fff.getHeapMemorySize(),xrange(1462-10,1462+10)) + self.assertIn(fff[0,-1].getHeapMemorySize(),xrange(711-10,711+10)) + f2=f[:50] + f2.setTime(2.,1,-1) + pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") + fff.appendFieldProfile(f2,mm,0,pfl) + self.assertIn(fff.getHeapMemorySize(),xrange(2178-100,2178+100)) + self.assertIn(fff.getProfile("pfl_NORM_QUAD4").getHeapMemorySize(),xrange(215-10,215+10)) + self.assertIn(fff[1,-1].getHeapMemorySize(),xrange(700-10,700+10)) + pass + + def testCurveLinearMesh1(self): + fname="Pyfile55.med" + mesh=MEDCouplingCurveLinearMesh(); + mesh.setTime(2.3,4,5); + mesh.setTimeUnit("us"); + mesh.setName("Example of Cuve linear mesh"); + mesh.setDescription("buildCLMesh"); + a1=DataArrayDouble(3*20,1); + a1.iota(7.) ; a1.rearrange(3); + mesh.setCoords(a1); + mesh.setNodeGridStructure([4,5]); + mesh.checkCoherency(); + # + m=MEDFileCurveLinearMesh() + m.setMesh(mesh) + d=DataArrayInt(20) ; d.iota(4) + m.setFamilyFieldArr(1,d) + d3=DataArrayInt(20) ; d3.iota(400) + m.setRenumFieldArr(1,d3) + d2=DataArrayInt(12) ; d2.iota(40) + m.setFamilyFieldArr(0,d2) + d4=DataArrayInt(21) ; d4.iota(4000) + self.assertRaises(InterpKernelException,m.setRenumFieldArr,1,d4) + d4.popBackSilent() + m.setRenumFieldArr(1,d4) + m.write(fname,2) + # + m1=MEDFileCurveLinearMesh(fname) + mm=m1.getMesh() + self.assertTrue(mm.isEqual(mesh,1e-12)) + # + m1=MEDFileMesh.New(fname) + self.assertTrue(isinstance(m1,MEDFileCurveLinearMesh)) + self.assertTrue(m1.getMesh().isEqual(mesh,1e-12)) + pass + pass unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i index 111fd0e2b..cbab3a4d0 100644 --- a/src/MEDLoader/Swig/MEDLoaderTypemaps.i +++ b/src/MEDLoader/Swig/MEDLoaderTypemaps.i @@ -27,6 +27,8 @@ static PyObject* convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) th ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileUMesh,owner); if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCMesh,owner); + if(dynamic_cast(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCurveLinearMesh,owner); if(!ret) throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !"); return ret; diff --git a/src/MEDPartitioner/CMakeLists.txt b/src/MEDPartitioner/CMakeLists.txt index 726e79780..69c64e11a 100644 --- a/src/MEDPartitioner/CMakeLists.txt +++ b/src/MEDPartitioner/CMakeLists.txt @@ -69,6 +69,7 @@ SET(medpartitionercpp_SOURCES MEDPARTITIONER_ParaDomainSelector.cxx MEDPARTITIONER_ConnectZone.cxx MEDPARTITIONER_SkyLineArray.cxx + MEDPARTITIONER_metis.c ) SET(medpartitionercpp_DEFINITIONS "${HDF5_DEFINITIONS} ${MED3_DEFINITIONS} ${LIBXML_DEFINITIONS} ${MPI_DEFINITIONS}") @@ -83,25 +84,24 @@ SET(medpartitionercpp_LDFLAGS medloader ) IF(MED_ENABLE_PARMETIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ParMetisGraph.hxx) SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ParMetisGraph.cxx) SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${PARMETIS_DEFINITIONS}") SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${PARMETIS_LIBS}) -ELSE(MED_ENABLE_PARMETIS) - IF(MED_ENABLE_METIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBS}) - ENDIF(MED_ENABLE_METIS) - IF(MED_ENABLE_SCOTCH) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBS}) - ENDIF(MED_ENABLE_SCOTCH) -ENDIF(MED_ENABLE_PARMETIS) - +ENDIF(MED_ENABLE_PARMETIS) +IF(MED_ENABLE_METIS) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx) + SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}") + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBS}) +ENDIF(MED_ENABLE_METIS) +IF(MED_ENABLE_SCOTCH) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx) + SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}") + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBS}) +ENDIF(MED_ENABLE_SCOTCH) + IF(MPI_IS_OK) SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_UtilsPara.cxx @@ -119,11 +119,11 @@ IF(MED_ENABLE_PARMETIS) SET_TARGET_PROPERTIES(medpartitioner_para PROPERTIES COMPILE_FLAGS "${medpartitionercpp_DEFINITIONS}") TARGET_LINK_LIBRARIES(medpartitioner_para medpartitionercpp ${medpartitionercpp_LDFLAGS}) INSTALL(TARGETS medpartitioner_para DESTINATION ${MED_salomebin_BINS}) -ELSE(MED_ENABLE_PARMETIS) - ADD_EXECUTABLE(medpartitioner medpartitioner.cxx) - SET_TARGET_PROPERTIES(medpartitioner PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${medpartitionercpp_DEFINITIONS}") - TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS}) - INSTALL(TARGETS medpartitioner DESTINATION ${MED_salomebin_BINS}) ENDIF(MED_ENABLE_PARMETIS) +ADD_EXECUTABLE(medpartitioner medpartitioner.cxx) +SET_TARGET_PROPERTIES(medpartitioner PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${medpartitionercpp_DEFINITIONS}") +TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS}) +INSTALL(TARGETS medpartitioner DESTINATION ${MED_salomebin_BINS}) + INSTALL(FILES ${medpartitionercpp_HEADERS_HXX} DESTINATION ${MED_salomeinclude_HEADERS}) diff --git a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx b/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx index 87dbc36be..bc31670da 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx @@ -48,13 +48,13 @@ void MEDPARTITIONER::JointFinder::findCommonDistantNodes() _node_node[i].resize(nbdomain); } int nbproc=_domain_selector->nbProcs(); - std::vector* > bbtree(nbdomain,(BBTree<3>*) 0); + std::vector bbtree(nbdomain,(BBTreeOfDim*) 0); std::vector bbxi(nbdomain,(double*) 0); std::vector rev(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); std::vector revIndx(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); int meshDim=-1; int spaceDim=-1; - + //init rev and revIndx and bbtree for my domain (of me:proc n) for (int mydomain=0; mydomain (bbx,0,0,myMesh->getNumberOfNodes(),-1e-12); + bbtree[mydomain]=new BBTreeOfDim( spaceDim, bbx,0,0,myMesh->getNumberOfNodes(),-1e-12); //keep bbx because need it in getIntersectingElems //no delete [] bbx yet bbxi[mydomain]=bbx; } - + //send my domains to other proc an receive other domains from other proc for (int isource=0; isourcegetProcessorID(itarget); - + std::vector vec(spaceDim*sourceMesh->getNumberOfNodes()); std::copy(sourceMesh->getCoords()->getConstPointer(),sourceMesh->getCoords()->getConstPointer()+sourceMesh->getNumberOfNodes()*spaceDim,&vec[0]); SendDoubleVec(vec,targetProc); - + //retrieving target data for storage in commonDistantNodes array std::vector localCorrespondency; RecvIntVec(localCorrespondency, targetProc); diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx index 0016d8595..4fc48e9ed 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx @@ -42,16 +42,17 @@ #include "PointLocator3DIntersectorP0P0.hxx" #include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "BBTree.txx" #ifdef HAVE_MPI2 #include #endif -#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS) +#ifdef MED_ENABLE_PARMETIS +#include "MEDPARTITIONER_ParMetisGraph.hxx" +#endif +#ifdef MED_ENABLE_METIS #include "MEDPARTITIONER_MetisGraph.hxx" #endif - #ifdef MED_ENABLE_SCOTCH #include "MEDPARTITIONER_ScotchGraph.hxx" #endif @@ -70,7 +71,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection() _domain_selector( 0 ), _i_non_empty_mesh(-1), _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(false), + _subdomain_boundary_creates( MyGlobals::_Creates_Boundary_Faces ), _family_splitting(false), _create_empty_groups(false), _joint_finder(0) @@ -99,7 +100,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection _i_non_empty_mesh(-1), _name(initialCollection._name), _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(false), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), _family_splitting(family_splitting), _create_empty_groups(create_empty_groups), _joint_finder(0) @@ -145,13 +146,13 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection std::cout<<"treating cell and face families"<getMesh(), - initialCollection.getCellFamilyIds(), - "cellFamily"); + this->getMesh(), + initialCollection.getCellFamilyIds(), + "cellFamily"); castIntField(initialCollection.getFaceMesh(), - this->getFaceMesh(), - initialCollection.getFaceFamilyIds(), - "faceFamily"); + this->getFaceMesh(), + initialCollection.getFaceFamilyIds(), + "faceFamily"); //treating groups #ifdef HAVE_MPI2 @@ -289,13 +290,13 @@ void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialColle array->decrRef(); // array is not used in this case } _mesh[inew]->zipCoords(); - + } } for (int i=0;i<(int)splitMeshes[inew].size();i++) if (splitMeshes[inew][i]!=0) splitMeshes[inew][i]->decrRef(); - } + } if (MyGlobals::_Verbose>300) std::cout << "proc " << rank << " : castCellMeshes end fusing" << std::endl; } @@ -313,21 +314,23 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC { double* bbox; - BBTree<3>* tree; + BBTreeOfDim* tree = 0; + int dim = 3; if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) { // std::map >, int > nodeClassifier; - int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes(); - bbox=new double[nvertices*2*3]; ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords(); double* coordsPtr=coords->getPointer(); + dim = coords->getNumberOfComponents(); + int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes(); + bbox=new double[nvertices*2*dim]; - for (int i=0; i(bbox,0,0,nvertices,1e-9); + tree=new BBTreeOfDim( dim, bbox,0,0,nvertices,1e-9); } for (int inew=0; inew<_topology->nbDomain(); inew++) @@ -343,7 +346,7 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC ParaMEDMEM::DataArrayDouble* coords = mesh->getCoords(); for (int inode=0; inodegetNumberOfNodes();inode++) { - double* coordsPtr=coords->getPointer()+inode*3; + double* coordsPtr=coords->getPointer()+inode*dim; vector elems; tree->getElementsAroundPoint(coordsPtr,elems); if (elems.size()==0) continue; @@ -353,52 +356,55 @@ void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialC } else if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) #else - if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) + if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) #endif - { - ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords(); - for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++) - { - double* coordsPtr=coords->getPointer()+inode*3; - vector elems; - tree->getElementsAroundPoint(coordsPtr,elems); - if (elems.size()==0) continue; - nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); - } - } + { + ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords(); + for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++) + { + double* coordsPtr=coords->getPointer()+inode*dim; + vector elems; + tree->getElementsAroundPoint(coordsPtr,elems); + if (elems.size()==0) continue; + nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); + } + } } if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) { delete tree; delete[] bbox; } - } + } } void getNodeIds(ParaMEDMEM::MEDCouplingUMesh& meshOne, ParaMEDMEM::MEDCouplingUMesh& meshTwo, std::vector& nodeIds) { using std::vector; + using MEDPARTITIONER::BBTreeOfDim; if (!&meshOne || !&meshTwo) return; //empty or not existing double* bbox; - BBTree<3>* tree; + BBTreeOfDim* tree = 0; int nv1=meshOne.getNumberOfNodes(); - bbox=new double[nv1*6]; ParaMEDMEM::DataArrayDouble* coords=meshOne.getCoords(); + int dim = coords->getNumberOfComponents(); + + bbox=new double[nv1*2*dim]; double* coordsPtr=coords->getPointer(); - for (int i=0; i(bbox,0,0,nv1,1e-9); - + tree=new BBTreeOfDim( dim, bbox,0,0,nv1,1e-9); + int nv2=meshTwo.getNumberOfNodes(); nodeIds.resize(nv2,-1); coords=meshTwo.getCoords(); for (int inode=0; inodegetPointer()+inode*3; + double* coordsPtr2=coords->getPointer()+inode*dim; vector elems; tree->getElementsAroundPoint(coordsPtr2,elems); if (elems.size()==0) continue; @@ -416,31 +422,30 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle const std::multimap, std::pair >& nodeMapping, std::vector > >& new2oldIds) { - //splitMeshes structure will contain the partition of //the old faces on the new ones //splitMeshes[4][2] contains the faces from old domain 2 //that have to be added to domain 4 - + using std::vector; using std::map; using std::multimap; using std::pair; using std::make_pair; - + if (MyGlobals::_Verbose>10) std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes" << std::endl; if (_topology==0) throw INTERP_KERNEL::Exception("Topology has not been defined on call to castFaceMeshes"); - + int nbNewDomain=_topology->nbDomain(); int nbOldDomain=initialCollection.getTopology()->nbDomain(); - + vector& meshesCastFrom=initialCollection.getFaceMesh(); vector& meshesCastTo=this->getFaceMesh(); - + vector< vector > splitMeshes; - + splitMeshes.resize(nbNewDomain); for (int inew=0; inewgetNumberOfCells()>0) myMeshes.push_back(umesh); } - + + ParaMEDMEM::MEDCouplingUMesh *bndMesh = 0; + if ( _subdomain_boundary_creates && + _mesh[inew] && + _mesh[inew]->getNumberOfCells()>0 ) + { + bndMesh = + ((ParaMEDMEM::MEDCouplingUMesh *)_mesh[inew]->buildBoundaryMesh(/*keepCoords=*/true)); + if (bndMesh->getNumberOfCells()>0) + myMeshes.push_back( bndMesh ); + } + if (myMeshes.size()>0) { meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(myMeshes); @@ -592,6 +608,8 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle for (int iold=0; iolddecrRef(); + if ( bndMesh ) + bndMesh->decrRef(); } if (MyGlobals::_Verbose>300) std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes end fusing" << std::endl; @@ -600,9 +618,9 @@ void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialColle void MEDPARTITIONER::MeshCollection::castIntField(std::vector& meshesCastFrom, - std::vector& meshesCastTo, - std::vector& arrayFrom, - std::string nameArrayTo) + std::vector& meshesCastTo, + std::vector& arrayFrom, + std::string nameArrayTo) { using std::vector; @@ -613,16 +631,16 @@ void MEDPARTITIONER::MeshCollection::castIntField(std::vector99) std::cout<<"making accelerating structures"<* > acceleratingStructures(ioldMax); + std::vector acceleratingStructures(ioldMax); std::vectorbbox(ioldMax); for (int iold =0; iold< ioldMax; iold++) if (isParallelMode() && _domain_selector->isMyDomain(iold)) { ParaMEDMEM::DataArrayDouble* sourceCoords=meshesCastFrom[iold]->getBarycenterAndOwner(); bbox[iold]=sourceCoords->computeBBoxPerTuple(1.e-6); - acceleratingStructures[iold]=new BBTree<3,int> (bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples()); + acceleratingStructures[iold]=new BBTreeOfDim( sourceCoords->getNumberOfComponents(), bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples()); + sourceCoords->decrRef(); } - // send-recv operations #ifdef HAVE_MPI2 for (int inew=0; inew* myTree) + const BBTreeOfDim* myTree) { if (sourceMesh.getNumberOfCells()<=0) return; //empty mesh could exist @@ -697,21 +715,22 @@ void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold, const double* tc=targetCoords->getConstPointer(); int targetSize=targetMesh.getNumberOfCells(); int sourceSize=sourceMesh.getNumberOfCells(); -if (MyGlobals::_Verbose>200) -std::cout<<"remap vers target de taille "<200) + std::cout<<"remap vers target de taille "< ccI; std::string str,cle; str=nameArrayTo+"_toArray"; cle=Cle1ToStr(str,inew); int* toArray; - const BBTree<3>* tree; + const BBTreeOfDim* tree; bool cleantree=false; ParaMEDMEM::DataArrayDouble* sourceBBox=0; + int dim = targetCoords->getNumberOfComponents(); if (myTree==0) { sourceBBox=sourceMesh.getBarycenterAndOwner()->computeBBoxPerTuple(1e-8); - tree=new BBTree<3> (sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10); + tree=new BBTreeOfDim( dim, sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10); cleantree=true; } else tree=myTree; @@ -730,17 +749,28 @@ std::cout<<"remap vers target de taille "<second->getPointer(); } - + + std::map< int, int > isource2nb; // count coincident elements + std::map::iterator i2nb; + for (int itargetnode=0; itargetnode intersectingElems; - tree->getElementsAroundPoint(tc+itargetnode*3,intersectingElems); // to be changed in 2D + tree->getElementsAroundPoint(tc+itargetnode*dim,intersectingElems); if (intersectingElems.size()!=0) { int isourcenode=intersectingElems[0]; - toArray[itargetnode]=fromArray[isourcenode]; - ccI.push_back(itargetnode); - ccI.push_back(isourcenode); + if ( intersectingElems.size() > 1 ) + { + i2nb = isource2nb.insert( std::make_pair( isourcenode, 0 )).first; + isourcenode = intersectingElems[ i2nb->second++ ]; + } + if ( isourcenode < sourceSize ) // protection from invalid elements + { + toArray[itargetnode]=fromArray[isourcenode]; + ccI.push_back(itargetnode); + ccI.push_back(isourcenode); + } } } if (MyGlobals::_Verbose>200) @@ -751,12 +781,11 @@ std::cout<<"remap vers target de taille "<decrRef(); if (cleantree) delete tree; if (sourceBBox !=0) sourceBBox->decrRef(); - - } +} void MEDPARTITIONER::MeshCollection::castAllFields(MeshCollection& initialCollection, std::string nameArrayTo) { @@ -906,6 +935,232 @@ void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold, } } +//================================================================================ +/*! + * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces" + * group (where "n" and "p" are domain IDs) + */ +//================================================================================ + +void MEDPARTITIONER::MeshCollection::buildConnectZones() +{ + if ( getMeshDimension() < 2 ) + return; + + using ParaMEDMEM::MEDCouplingUMesh; + using ParaMEDMEM::DataArrayDouble; + using ParaMEDMEM::DataArrayInt; + + std::vector& faceMeshes = getFaceMesh(); + int nbMeshes = faceMeshes.size(); + + //preparing bounding box trees for accelerating search of coincident faces + std::vector bbTrees(nbMeshes); + std::vectorbbox (nbMeshes); + for (int inew = 0; inew < nbMeshes-1; inew++) + if ( !isParallelMode() || _domain_selector->isMyDomain(inew) ) + { + DataArrayDouble* bcCoords = faceMeshes[inew]->getBarycenterAndOwner(); + bbox [inew] = bcCoords->computeBBoxPerTuple(1.e-6); + bbTrees[inew] = new BBTreeOfDim( bcCoords->getNumberOfComponents(), + bbox[inew]->getConstPointer(),0,0, + bbox[inew]->getNumberOfTuples()); + bcCoords->decrRef(); + } + + // loop on domains to find joint faces between them + for (int inew1 = 0; inew1 < nbMeshes; inew1++ ) + { + for (int inew2 = inew1+1; inew2 < nbMeshes; inew2++ ) + { + MEDCouplingUMesh* mesh1 = 0; + MEDCouplingUMesh* mesh2 = 0; + //MEDCouplingUMesh* recvMesh = 0; + bool mesh1Here = true, mesh2Here = true; + if (isParallelMode()) + { +#ifdef HAVE_MPI2 + mesh1Here = _domain_selector->isMyDomain(inew1); + mesh2Here = _domain_selector->isMyDomain(inew2); + if ( !mesh1Here && mesh2Here ) + { + //send mesh2 to domain of mesh1 + _domain_selector->sendMesh(*faceMeshes[inew2], + _domain_selector->getProcessorID(inew1)); + } + else if ( mesh1Here && !mesh2Here ) + { + //receiving mesh2 from a distant domain + _domain_selector->recvMesh(mesh2,_domain_selector->getProcessorID(inew2)); + if ( faceMeshes[ inew2 ] ) + faceMeshes[ inew2 ]->decrRef(); + faceMeshes[ inew2 ] = mesh2; + } +#endif + } + if ( mesh1Here && !mesh1 ) mesh1 = faceMeshes[ inew1 ]; + if ( mesh2Here && !mesh2 ) mesh2 = faceMeshes[ inew2 ]; + + // find coincident faces + std::vector< int > faces1, faces2; + if ( mesh1 && mesh2 ) + { + const DataArrayDouble* coords2 = mesh2->getBarycenterAndOwner(); + const double* c2 = coords2->getConstPointer(); + const int dim = coords2->getNumberOfComponents(); + const int nbFaces2 = mesh2->getNumberOfCells(); + const int nbFaces1 = mesh1->getNumberOfCells(); + + for (int i2 = 0; i2 < nbFaces2; i2++) + { + std::vector coincFaces; + bbTrees[inew1]->getElementsAroundPoint( c2+i2*dim, coincFaces ); + if (coincFaces.size()!=0) + { + int i1 = coincFaces[0]; + // if ( coincFaces.size() > 1 ) + // { + // i2nb = isource2nb.insert( std::make_pair( i1 , 0 )).first; + // i1 = coincFaces[ i2nb->second++ ]; + // } + if ( i1 < nbFaces1 ) // protection from invalid elements + { + faces1.push_back( i1 ); + faces2.push_back( i2 ); + } + } + } + coords2->decrRef(); + } + + if ( isParallelMode()) + { +#ifdef HAVE_MPI2 + if ( mesh1Here && !mesh2Here ) + { + //send faces2 to domain of recvMesh + SendIntVec(faces2, _domain_selector->getProcessorID(inew2)); + } + else if ( !mesh1Here && mesh2Here ) + { + //receiving ids of faces from a domain of mesh1 + RecvIntVec(faces2, _domain_selector->getProcessorID(inew1)); + } +#endif + } + // if ( recvMesh ) + // recvMesh->decrRef(); + + // Create group "JOINT_inew1_inew2_Faces" and corresponding families + for ( int is2nd = 0; is2nd < 2; ++is2nd ) + { + createJointGroup( is2nd ? faces2 : faces1, + inew1 , inew2, is2nd ); + } + + } // loop on the 2nd domains (inew2) + } // loop on the 1st domains (inew1) + + + // delete bounding box trees + for (int inew = 0; inew < nbMeshes-1; inew++) + if (isParallelMode() && _domain_selector->isMyDomain(inew)) + { + bbox[inew]->decrRef(); + delete bbTrees[inew]; + } +} + +//================================================================================ +/*! + * \brief Create group "JOINT_inew1_inew2_Faces" and corresponding families + * \param faces - face ids to include into the group + * \param inew1 - index of the 1st domain + * \param inew2 - index of the 2nd domain + * \param is2nd - in which (1st or 2nd) domain to create the group + */ +//================================================================================ + +void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >& faces, + const int inew1, + const int inew2, + const bool is2nd ) +{ + // get the name of JOINT group + std::string groupName; + { + std::ostringstream oss; + oss << "JOINT_" + << (is2nd ? inew2 : inew1 ) << "_" + << (is2nd ? inew1 : inew2 ) << "_" + << ( getMeshDimension()==2 ? "Edge" : "Face" ); + groupName = oss.str(); + } + + // remove existing "JOINT_*" group + _group_info.erase( groupName ); + + // get family IDs array + int* famIDs = 0; + int inew = (is2nd ? inew2 : inew1 ); + int totalNbFaces = _face_mesh[ inew ] ? _face_mesh[ inew ]->getNumberOfCells() : 0; + std::string cle = Cle1ToStr( "faceFamily_toArray", inew ); + if ( !_map_dataarray_int.count(cle) ) + { + if ( totalNbFaces > 0 ) + { + ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); + p->alloc( totalNbFaces, 1 ); + p->fillWithZero(); + famIDs = p->getPointer(); + _map_dataarray_int[cle]=p; + } + } + else + { + famIDs = _map_dataarray_int.find(cle)->second->getPointer(); + } + // find a family ID of an existing JOINT group + int familyID = 0; + std::map::iterator name2id = _family_info.find( groupName ); + if ( name2id != _family_info.end() ) + familyID = name2id->second; + + // remove faces from the familyID-the family + if ( familyID != 0 && famIDs ) + for ( size_t i = 0; i < totalNbFaces; ++i ) + if ( famIDs[i] == familyID ) + famIDs[i] = 0; + + if ( faces.empty() ) + return; + + if ( familyID == 0 ) // generate a family ID for JOINT group + { + std::set< int > familyIDs; + for ( name2id = _family_info.begin(); name2id != _family_info.end(); ++name2id ) + familyIDs.insert( name2id->second ); + // find the next free family ID + int freeIdCount = inew1 * getNbOfGlobalMeshes() + inew2 + is2nd; + do + { + if ( !familyIDs.count( ++familyID )) + --freeIdCount; + } + while ( freeIdCount > 0 ); + } + + // push faces to familyID-th group + if ( faces.back() >= totalNbFaces ) + throw INTERP_KERNEL::Exception("MeshCollection::createJointGroup(): to high face ID"); + for ( size_t i = 0; i < faces.size(); ++i ) + famIDs[ faces[i] ] = familyID; + + // register JOINT group and family + _family_info[ groupName ] = familyID; // name of the group and family is same + _group_info [ groupName ].push_back( groupName ); +} + /*! constructing the MESH collection from a distributed file * * \param filename name of the master file containing the list of all the MED files @@ -917,7 +1172,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename) _domain_selector( 0 ), _i_non_empty_mesh(-1), _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(false), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), _family_splitting(false), _create_empty_groups(false), _joint_finder(0) @@ -961,7 +1216,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, Para _domain_selector( &domainSelector ), _i_non_empty_mesh(-1), _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(false), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), _family_splitting(false), _create_empty_groups(false), _joint_finder(0) @@ -1121,7 +1376,7 @@ MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, cons _i_non_empty_mesh(-1), _name(meshname), _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(false), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), _family_splitting(false), _create_empty_groups(false), _joint_finder(0) @@ -1186,8 +1441,8 @@ MEDPARTITIONER::MeshCollection::~MeshCollection() void MEDPARTITIONER::MeshCollection::write(const std::string& filename) { //building the connect zones necessary for writing joints - // if (_topology->nbDomain()>1) - // buildConnectZones(); + if (_topology->nbDomain()>1 && _subdomain_boundary_creates ) + buildConnectZones(); //suppresses link with driver so that it can be changed for writing delete _driver; _driver=0; @@ -1336,10 +1591,12 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray if (MyGlobals::_Verbose>50) std::cout<<"getting nodal connectivity"<isMyDomain(idomain)) continue; + meshDim = _mesh[idomain]->getMeshDimension(); ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New(); ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); @@ -1428,9 +1685,9 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray for (std::map,int>::const_iterator it=cell2cellcounter.begin(); it!=cell2cellcounter.end(); it++) - if (it->second>=3) + if (it->second>=meshDim) { - cell2cell.insert(std::make_pair(it->first.first,it->first.second)); //should be adapted for 2D! + cell2cell.insert(std::make_pair(it->first.first,it->first.second)); cell2cell.insert(std::make_pair(it->first.second, it->first.first)); } @@ -1473,7 +1730,7 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray index.push_back(idep); } } - + array=new MEDPARTITIONER::SkyLineArray(index,value); if (MyGlobals::_Verbose>100) @@ -1517,18 +1774,30 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb int* edgeweights=0; buildCellGraph(array,edgeweights); - Graph* cellGraph; + Graph* cellGraph = 0; switch (split) { case Graph::METIS: -#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS) - if (MyGlobals::_Verbose>10) - std::cout << "METISGraph" << std::endl; - cellGraph=new METISGraph(array,edgeweights); -#else - throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); + if ( isParallelMode() && MyGlobals::_World_Size > 1 ) + { +#ifdef MED_ENABLE_PARMETIS + if (MyGlobals::_Verbose>10) + std::cout << "ParMETISGraph" << std::endl; + cellGraph=new ParMETISGraph(array,edgeweights); #endif + } + if ( !cellGraph ) + { +#ifdef MED_ENABLE_METIS + if (MyGlobals::_Verbose>10) + std::cout << "METISGraph" << std::endl; + cellGraph=new METISGraph(array,edgeweights); +#endif + } + if ( !cellGraph ) + throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); break; + case Graph::SCOTCH: #ifdef MED_ENABLE_SCOTCH if (MyGlobals::_Verbose>10) @@ -1709,7 +1978,7 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell() { for (int inew=0; inew<_topology->nbDomain(); inew++) { - if (isParallelMode() && _domain_selector->isMyDomain(inew)) + if (!isParallelMode() || _domain_selector->isMyDomain(inew)) { if (MyGlobals::_Verbose>200) std::cout << "proc " << MyGlobals::_Rank << " : filterFaceOnCell on inewDomain " << inew << " nbOfFaces " << _face_mesh[inew]->getNumberOfCells() << std::endl; @@ -1721,13 +1990,13 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell() getNodeIds(*mcel, *mfac, nodeIds); if (nodeIds.size()==0) continue; //one empty mesh nothing to do - + ParaMEDMEM::DataArrayInt *revNodalCel=ParaMEDMEM::DataArrayInt::New(); ParaMEDMEM::DataArrayInt *revNodalIndxCel=ParaMEDMEM::DataArrayInt::New(); mcel->getReverseNodalConnectivity(revNodalCel,revNodalIndxCel); int *revC=revNodalCel->getPointer(); int *revIndxC=revNodalIndxCel->getPointer(); - + std::vector< int > faceOnCell; std::vector< int > faceNotOnCell; int nbface=mfac->getNumberOfCells(); @@ -1737,11 +2006,20 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell() std::vector< int > inodesFace; mfac->getNodeIdsOfCell(iface, inodesFace); int nbnodFace=inodesFace.size(); + if ( nbnodFace != mfac->getNumberOfNodesInCell( iface )) + continue; // invalid node ids //set inodesFace in mcel - for (int i=0; i= 0 ); + if ( nbok != nbnodFace ) + continue; int inod=inodesFace[0]; if (inod<0) - std::cout << "filterFaceOnCell problem 1" << std::endl; + { + std::cout << "filterFaceOnCell problem 1" << std::endl; + continue; + } int nbcell=revIndxC[inod+1]-revIndxC[inod]; for (int j=0; jdecrRef(); revNodalIndxCel->decrRef(); - - std::string keyy; - keyy=Cle1ToStr("filterFaceOnCell",inew); - _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell); - keyy=Cle1ToStr("filterNotFaceOnCell",inew); - _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell); + + // std::string keyy; + // keyy=Cle1ToStr("filterFaceOnCell",inew); + // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell); + // keyy=Cle1ToStr("filterNotFaceOnCell",inew); + // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell); + + // filter the face mesh + if ( faceOnCell.empty() ) + _face_mesh[inew] = CreateEmptyMEDCouplingUMesh(); + else + _face_mesh[inew] = (ParaMEDMEM::MEDCouplingUMesh *) + mfac->buildPartOfMySelf( &faceOnCell[0], &faceOnCell[0] + faceOnCell.size(),true); + mfac->decrRef(); + + // filter the face families + std::string key = Cle1ToStr("faceFamily_toArray",inew); + if ( getMapDataArrayInt().count( key )) + { + ParaMEDMEM::DataArrayInt * & fam = getMapDataArrayInt()[ key ]; + ParaMEDMEM::DataArrayInt * famFilter = ParaMEDMEM::DataArrayInt::New(); + famFilter->alloc(faceOnCell.size(),1); + int* pfamFilter = famFilter->getPointer(); + int* pfam = fam->getPointer(); + for ( size_t i=0; idecrRef(); + fam = famFilter; + } } } } diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx index 2e6827a73..622b2a234 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx @@ -22,6 +22,7 @@ #include "MEDPARTITIONER.hxx" #include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_Utils.hxx" #include "MEDCouplingUMesh.hxx" @@ -143,6 +144,9 @@ namespace MEDPARTITIONER const std::multimap, std::pair >& nodeMapping, std::vector > >& new2oldIds); + //constructing connect zones + void buildConnectZones(); + private: void castIntField(std::vector& meshesCastFrom, std::vector& meshesCastTo, @@ -156,16 +160,21 @@ namespace MEDPARTITIONER void remapIntField(int inew, int iold, - const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, - const ParaMEDMEM::MEDCouplingUMesh& targetMesh, - const int* fromArray, - std::string nameArrayTo, - const BBTree<3,int>* tree); + const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, + const ParaMEDMEM::MEDCouplingUMesh& targetMesh, + const int* fromArray, + std::string nameArrayTo, + const BBTreeOfDim* tree); void remapDoubleField(int inew, int iold, ParaMEDMEM::DataArrayDouble* fromArray, std::string nameArrayTo, std::string descriptionField); + + void createJointGroup( const std::vector< int >& faces, + const int inew1, + const int inew2, + const bool is2nd ); private: //link to mesh_collection topology diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx index c2c997d0e..f41349581 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx @@ -228,18 +228,18 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile std::vector meshes; ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain); ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain); - ParaMEDMEM::MEDCouplingUMesh* faceMeshFilter=0; + //ParaMEDMEM::MEDCouplingUMesh* faceMeshFilter=0; std::string finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); - std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain); - ParaMEDMEM::DataArrayInt* filter=0; - if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end()) - { - filter=_collection->getMapDataArrayInt().find(cleFilter)->second; - int* index=filter->getPointer(); - faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true); - faceMesh=faceMeshFilter; - } + // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain); + // ParaMEDMEM::DataArrayInt* filter=0; + // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end()) + // { + // filter=_collection->getMapDataArrayInt().find(cleFilter)->second; + // int* index=filter->getPointer(); + // faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true); + // faceMesh=faceMeshFilter; + // } cellMesh->setName(finalMeshName.c_str()); meshes.push_back(cellMesh); @@ -250,60 +250,45 @@ void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfile meshes.push_back(faceMesh); } - ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0; - if (MyGlobals::_Creates_Boundary_Faces>0) - { - //try to write Boundary meshes - bool keepCoords=false; //TODO or true - boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords); - boundaryMesh->setName("boundaryMesh"); - } - + //ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0; + // if (MyGlobals::_Creates_Boundary_Faces>0) + // { + // //try to write Boundary meshes + // bool keepCoords=false; //TODO or true + // boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords); + // boundaryMesh->setName("boundaryMesh"); + // } + MEDLoader::WriteUMeshes(distfilename.c_str(), meshes, true); - if (faceMeshFilter!=0) - faceMeshFilter->decrRef(); - - if (boundaryMesh!=0) - { - //doing that testMesh becomes second mesh sorted by alphabetical order of name - MEDLoader::WriteUMesh(distfilename.c_str(), boundaryMesh, false); - boundaryMesh->decrRef(); - } + // if (faceMeshFilter!=0) + // faceMeshFilter->decrRef(); + + // if (boundaryMesh!=0) + // { + // //doing that testMesh becomes second mesh sorted by alphabetical order of name + // MEDLoader::WriteUMesh(distfilename.c_str(), boundaryMesh, false); + // boundaryMesh->decrRef(); + // } ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(distfilename.c_str(), _collection->getMesh(idomain)->getName()); - + mfm->setFamilyInfo(_collection->getFamilyInfo()); mfm->setGroupInfo(_collection->getGroupInfo()); - + std::string key=Cle1ToStr("faceFamily_toArray",idomain); - if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) + if ( meshes.size() == 2 && + _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) { ParaMEDMEM::DataArrayInt *fam=_collection->getMapDataArrayInt().find(key)->second; - ParaMEDMEM::DataArrayInt *famFilter=0; - if (filter!=0) - { - int* index=filter->getPointer(); - int nbTuples=filter->getNbOfElems(); - //not the good one...buildPartOfMySelf do not exist for DataArray - //Filter=fam->renumberAndReduce(index, filter->getNbOfElems()); - famFilter=ParaMEDMEM::DataArrayInt::New(); - famFilter->alloc(nbTuples,1); - int* pfamFilter=famFilter->getPointer(); - int* pfam=fam->getPointer(); - for (int i=0; isetFamilyFieldArr(-1,fam); - famFilter->decrRef(); - } + mfm->setFamilyFieldArr(-1,fam); } - + key=Cle1ToStr("cellFamily_toArray",idomain); if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second); - + mfm->write(distfilename.c_str(),0); key="/inewFieldDouble="+IntToStr(idomain)+"/"; - + std::map::iterator it; int nbfFieldFound=0; for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) diff --git a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx index 5f89b9573..05a83a28b 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx @@ -25,12 +25,10 @@ #include -#ifdef MED_ENABLE_METIS extern "C" { -#include "metis.h" +#include "MEDPARTITIONER_metis.h" } -#endif using namespace MEDPARTITIONER; @@ -90,11 +88,11 @@ void METISGraph::partGraph(int ndomain, if (MyGlobals::_Verbose>10) std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl; if (options_string != "k") - METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); + MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); else - METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); + MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); } else //force this case because METIS send all 1 in value { diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx index 5e85a6f94..f042c44bf 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx @@ -17,7 +17,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "MEDPARTITIONER_MetisGraph.hxx" +#include "MEDPARTITIONER_ParMetisGraph.hxx" #include "MEDPARTITIONER_ParaDomainSelector.hxx" #include "MEDPARTITIONER_Utils.hxx" @@ -26,26 +26,28 @@ #include #ifdef MED_ENABLE_PARMETIS -#include -#include "parmetis.h" +#include +// #if PARMETIS_MAJOR_VERSION == 4 +// #define ParMETIS_PartKway ParMETIS_V3_PartKway +// #endif #endif using namespace MEDPARTITIONER; -METISGraph::METISGraph():Graph() +ParMETISGraph::ParMETISGraph():Graph() { } -METISGraph::METISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight) +ParMETISGraph::ParMETISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight) :Graph(graph,edgeweight) { } -METISGraph::~METISGraph() +ParMETISGraph::~ParMETISGraph() { } -void METISGraph::partGraph(int ndomain, +void ParMETISGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector *parallelizer) { @@ -53,7 +55,7 @@ void METISGraph::partGraph(int ndomain, vector ran,vx,va; //for randomize if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl; // number of graph vertices int n=_graph->getNumberOf(); @@ -81,12 +83,12 @@ void METISGraph::partGraph(int ndomain, // output parameters int edgecut; #if !defined(MED_ENABLE_PARMETIS) - throw INTERP_KERNEL::Exception("METISGraph::partGraph : PARMETIS is not available. Check your products, please."); + throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please."); #else int* partition=new int[n]; if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph ParMETIS_PartKway new" << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl; int * vtxdist=parallelizer->getProcVtxdist(); MPI_Comm comm=MPI_COMM_WORLD; ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx new file mode 100644 index 000000000..ffc689d11 --- /dev/null +++ b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_ParMETISGraph_HXX__ +#define __MEDPARTITIONER_ParMETISGraph_HXX__ + +#include "MEDPARTITIONER_Graph.hxx" + +#include + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT ParMETISGraph : public Graph + { + public: + ParMETISGraph(); + ParMETISGraph(MEDPARTITIONER::SkyLineArray*, int *edgeweight=0); + virtual ~ParMETISGraph(); + void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); + }; +} + +#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx index 48f7a6ca6..055262274 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx @@ -100,6 +100,7 @@ bool MEDPARTITIONER::ParaDomainSelector::isOnDifferentHosts() const MPI_Allreduce( &same, &sum_same, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); return (sum_same != nbProcs()); #endif + return false; } /*! diff --git a/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx b/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx index 6bbe1a86c..64488d052 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx @@ -826,3 +826,54 @@ ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh() umesh->checkCoherency(); return umesh; } + +namespace MEDPARTITIONER +{ + BBTreeOfDim::BBTreeOfDim( int dim, + const double* bbs, + int* elems, + int level, + int nbelems, + double epsilon) + { + switch ( dim ) + { + case 3: + _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 3 >; + break; + case 2: + _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 2 >; + break; + case 1: + _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 1 >; + break; + default: + _tree=0; + throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension"); + } + } + + BBTreeOfDim::~BBTreeOfDim() + { + delete (BBTree<3>*)_tree; + } + + void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr, + std::vector& elems ) const + { + BBTreeOfDim* me = (BBTreeOfDim*) this; + (me->*_PgetElementsAroundPoint) ( coordsPtr, elems ); + } + void BBTreeOfDim::getIntersectingElems(const double* bb, + std::vector& elems) const + { + BBTreeOfDim* me = (BBTreeOfDim*) this; + (me->*_PgetIntersectingElems) ( bb, elems ); + } +} diff --git a/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx b/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx index 02b74cf28..1fcdc33a2 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx +++ b/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx @@ -23,6 +23,7 @@ #include "MEDPARTITIONER.hxx" #include "MEDCouplingUMesh.hxx" +#include "BBTree.txx" #include #include @@ -133,5 +134,44 @@ namespace MEDPARTITIONER /*! used for descriptions of components of fields for example...*/ static std::vector _General_Informations; }; + + + + /*! + * \brief Class encapsulating BBTree of dimension given at construction and + * providing all features of BBTree + */ + class BBTreeOfDim + { + void * _tree; + void (BBTreeOfDim::*_PgetElementsAroundPoint)( const double* coordsPtr, + std::vector& elems ) const; + void (BBTreeOfDim::*_PgetIntersectingElems)( const double* bb, + std::vector& elems ) const; + + template< int dim> + void _getElementsAroundPoint( const double* coordsPtr, + std::vector& elems ) const + { + ((BBTree*)_tree)->getElementsAroundPoint( coordsPtr, elems ); + } + template< int dim> + void _getIntersectingElems(const double* bb, + std::vector& elems) const + { + ((BBTree*)_tree)->getIntersectingElems( bb, elems ); + } + public: + + BBTreeOfDim( int dim, + const double* bbs, + int* elems, + int level, + int nbelems, + double epsilon=1e-12); + ~BBTreeOfDim(); + void getElementsAroundPoint(const double* coordsPtr, std::vector& elems ) const; + void getIntersectingElems (const double* bb, std::vector& elems) const; + }; } #endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.c b/src/MEDPartitioner/MEDPARTITIONER_metis.c new file mode 100644 index 000000000..ec8cde2bc --- /dev/null +++ b/src/MEDPartitioner/MEDPARTITIONER_metis.c @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// Creation of this C code is forced by the following. +// +// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes +// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h +// that breaks compilation. To workaround this problem we create a wrapping C +// function, inclusion of whose declaration causes no problem. + +#include "MEDPARTITIONER_metis.h" + +#if defined(MED_ENABLE_METIS) + #include +#else + typedef int idxtype; +#endif + +void MEDPARTITIONER_METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ +#if defined(MED_ENABLE_METIS) + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, + adjwgt, wgtflag, numflag, nparts, + options, edgecut, part); +#endif +} + +void MEDPARTITIONER_METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ +#if defined(MED_ENABLE_METIS) + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, + adjwgt, wgtflag, numflag, nparts, + options, edgecut, part); +#endif +} diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.h b/src/MEDPartitioner/MEDPARTITIONER_metis.h new file mode 100644 index 000000000..6b2832d90 --- /dev/null +++ b/src/MEDPartitioner/MEDPARTITIONER_metis.h @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// Creation of this C code is forced by the following. +// +// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes +// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h +// that breaks compilation. To workaround this problem we create a wrapping C +// function, inclusion of whose declaration causes no problem. + + +void MEDPARTITIONER_METIS_PartGraphRecursive(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); + +void MEDPARTITIONER_METIS_PartGraphKway(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); diff --git a/src/MEDPartitioner/Makefile.am b/src/MEDPartitioner/Makefile.am index c6039a030..3efca0b19 100644 --- a/src/MEDPartitioner/Makefile.am +++ b/src/MEDPartitioner/Makefile.am @@ -40,19 +40,19 @@ MEDPARTITIONER.hxx \ MEDPARTITIONER_ParaDomainSelector.hxx \ MEDPARTITIONER_ConnectZone.hxx \ MEDPARTITIONER_SkyLineArray.hxx \ -MEDPARTITIONER_Topology.hxx +MEDPARTITIONER_Topology.hxx \ +MEDPARTITIONER_metis.h #compilation of medpartitioner_para OR EXCLUSIVE medpartitioner if MED_ENABLE_PARMETIS - salomeinclude_HEADERS+= MEDPARTITIONER_MetisGraph.hxx -else + salomeinclude_HEADERS+= MEDPARTITIONER_ParMetisGraph.hxx +endif if MED_ENABLE_METIS salomeinclude_HEADERS += MEDPARTITIONER_MetisGraph.hxx endif if MED_ENABLE_SCOTCH salomeinclude_HEADERS += MEDPARTITIONER_ScotchGraph.hxx endif -endif dist_libmedpartitioner_la_SOURCES= \ MEDPARTITIONER_MeshCollection.cxx \ @@ -65,7 +65,8 @@ MEDPARTITIONER_UserGraph.cxx\ MEDPARTITIONER_Utils.cxx \ MEDPARTITIONER_ParaDomainSelector.cxx \ MEDPARTITIONER_ConnectZone.cxx \ -MEDPARTITIONER_SkyLineArray.cxx +MEDPARTITIONER_SkyLineArray.cxx \ +MEDPARTITIONER_metis.c if MPI_IS_OK dist_libmedpartitioner_la_SOURCES+= \ @@ -76,14 +77,13 @@ endif if MED_ENABLE_PARMETIS dist_libmedpartitioner_la_SOURCES+= \ MEDPARTITIONER_ParMetisGraph.cxx -else +endif if MED_ENABLE_METIS dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_MetisGraph.cxx endif if MED_ENABLE_SCOTCH dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_ScotchGraph.cxx endif -endif libmedpartitioner_la_CPPFLAGS= $(MPI_INCLUDES) $(MED3_INCLUDES) $(HDF5_INCLUDES) \ $(LIBXML_INCLUDES) \ @@ -98,7 +98,7 @@ libmedpartitioner_la_LDFLAGS= if MED_ENABLE_PARMETIS libmedpartitioner_la_CPPFLAGS+= $(PARMETIS_CPPFLAGS) libmedpartitioner_la_LDFLAGS+= $(PARMETIS_LIBS) -else +endif if MED_ENABLE_METIS libmedpartitioner_la_CPPFLAGS += $(METIS_CPPFLAGS) libmedpartitioner_la_LDFLAGS += $(METIS_LIBS) @@ -107,25 +107,25 @@ if MED_ENABLE_SCOTCH libmedpartitioner_la_CPPFLAGS += $(SCOTCH_CPPFLAGS) libmedpartitioner_la_LDFLAGS += $(SCOTCH_LIBS) endif -endif libmedpartitioner_la_CXXFLAGS = @CXXTMPDPTHFLAGS@ libmedpartitioner_la_LDFLAGS+= $(MED3_LIBS_C_ONLY) $(HDF5_LIBS) $(STDLIB) $(LIBXML_LIBS) $(MPI_LIBS) ../INTERP_KERNEL/libinterpkernel.la ../MEDCoupling/libmedcoupling.la ../MEDLoader/libmedloader.la # Executables targets + +bin_PROGRAMS= medpartitioner +dist_medpartitioner_SOURCES= medpartitioner.cxx +medpartitioner_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS) +medpartitioner_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la +medpartitioner_CXXFLAGS = @CXXTMPDPTHFLAGS@ + if MED_ENABLE_PARMETIS bin_PROGRAMS=medpartitioner_para dist_medpartitioner_para_SOURCES= medpartitioner_para.cxx medpartitioner_para_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS) medpartitioner_para_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la medpartitioner_para_CXXFLAGS=@CXXTMPDPTHFLAGS@ -else - bin_PROGRAMS= medpartitioner - dist_medpartitioner_SOURCES= medpartitioner.cxx - medpartitioner_CPPFLAGS= $(libmedpartitioner_la_CPPFLAGS) - medpartitioner_LDADD= $(libmedpartitioner_la_LDFLAGS) -lm libmedpartitioner.la - medpartitioner_CXXFLAGS = @CXXTMPDPTHFLAGS@ endif diff --git a/src/MEDPartitioner/Test/CMakeLists.txt b/src/MEDPartitioner/Test/CMakeLists.txt index ee2bc2143..d58c6828a 100644 --- a/src/MEDPartitioner/Test/CMakeLists.txt +++ b/src/MEDPartitioner/Test/CMakeLists.txt @@ -58,12 +58,12 @@ IF(MPI_IS_OK) SET(MEDPARTITIONERTest_SOURCES ${MEDPARTITIONERTest_SOURCES} MEDPARTITIONERTestPara.cxx) SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${MPI_DEFINITIONS} ${PARMETIS_DEFINITIONS}") ENDIF(MED_ENABLE_PARMETIS) -ELSE(MPI_IS_OK) - IF(MED_ENABLE_METIS) - SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${METIS_DEFINITIONS}") - ENDIF(MED_ENABLE_METIS) ENDIF(MPI_IS_OK) +IF(MED_ENABLE_METIS) + SET(MEDPARTITIONERTest_DEFINITIONS "${MEDPARTITIONERTest_DEFINITIONS} ${METIS_DEFINITIONS}") +ENDIF(MED_ENABLE_METIS) + ADD_LIBRARY(MEDPARTITIONERTest SHARED ${MEDPARTITIONERTest_SOURCES}) SET_TARGET_PROPERTIES(MEDPARTITIONERTest PROPERTIES COMPILE_FLAGS "${MEDPARTITIONERTest_DEFINITIONS}") TARGET_LINK_LIBRARIES(MEDPARTITIONERTest ${MEDPARTITIONERTest_LDFLAGS}) diff --git a/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx b/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx index 1a3772363..86bf5e325 100644 --- a/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx +++ b/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx @@ -506,6 +506,7 @@ void MEDPARTITIONERTest::createTestMeshWithoutField() } mesh1->decrRef(); mesh2->decrRef(); + mfm->decrRef(); } { @@ -627,6 +628,7 @@ void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int //cout<<"\n"<decrRef(); } void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells() @@ -891,7 +893,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis() void MEDPARTITIONERTest::testMetisSmallSize() { -#if !defined(HAVE_MPI2) + //#if !defined(HAVE_MPI2) setSmallSize(); createTestMeshes(); std::string MetisOrScotch("metis"); @@ -899,7 +901,7 @@ void MEDPARTITIONERTest::testMetisSmallSize() verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); -#endif + //#endif } #endif @@ -973,7 +975,7 @@ void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch() void MEDPARTITIONERTest::testScotchSmallSize() { -#if !defined(HAVE_MPI2) + //#if !defined(HAVE_MPI2) setSmallSize(); createTestMeshes(); std::string MetisOrScotch("scotch"); @@ -981,7 +983,7 @@ void MEDPARTITIONERTest::testScotchSmallSize() verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); -#endif + //#endif } #endif @@ -1124,7 +1126,9 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std faceMesh->decrRef(); fusedCell->decrRef(); refusedCellMesh->decrRef(); + refusedMesh->decrRef(); cellMesh->decrRef(); + initialMesh->decrRef(); //done in ~collection //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); @@ -1213,8 +1217,10 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnC field1->decrRef(); field2->decrRef(); fusedCell->decrRef(); + refusedMesh->decrRef(); refusedCellMesh->decrRef(); cellMesh->decrRef(); + initialMesh->decrRef(); } void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch) @@ -1301,6 +1307,200 @@ void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnG field1->decrRef(); field2->decrRef(); fusedCell->decrRef(); + refusedMesh->decrRef(); refusedCellMesh->decrRef(); cellMesh->decrRef(); + initialMesh->decrRef(); +} + +//================================================================================ +/*! + * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements + */ +//================================================================================ + +void MEDPARTITIONERTest::testCreateBoundaryFaces2D() +{ + // Fixed complains are: + // - 2D is not available + // - groups and family handling is bugged (probably due to bug in the handling + // of arrayTo in castIntField()) + // - creates boundary faces option is not handled + + // Create a 2D mesh in a file + + const char fileName[] = "tmp_testCreateBoundaryFaces2D.med"; + + const int idFam1 = 3, idFam2 = 2; + int nbFam1, nbFam2, nbc; + { + const int nbX = 20, nbY = 15; + vector conn; + vector coor; + for (int j=0; j<=nbY; j++) + for (int i=0; i<=nbX; i++) + { + coor.push_back(i+.1); + coor.push_back(j+.2); + } + int ii; + for (int j=0; jsetMeshDimension(2); + + nbc=conn.size()/4; //nb of cells + mesh->allocateCells(nbc); + int* pConn = &conn[0]; + for(int i=0; iinsertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn); + mesh->finishInsertingCells(); + + int nbv=coor.size()/2; //nb of vertices + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 ); + mesh->setCoords(myCoords); + mesh->setName("FacesIn2D"); + myCoords->decrRef(); + mesh->checkCoherency(); + + // groups of cells + DataArrayInt* cellsFam=DataArrayInt::New(); + cellsFam->alloc(nbc,1); + nbFam1 = nbc/3, nbFam2 = nbc/2; + int iE = 0; + for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1; + for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2; + for ( ; iE < nbc; ) cellsFam->getPointer()[ iE++ ] = 0; + map theFamilies; + theFamilies["FAMILLE_ZERO"]=0; + theFamilies["Family1" ]=idFam1; + theFamilies["Family2" ]=idFam2; + map > theGroups; + theGroups["Group1"].push_back("Family1"); + theGroups["Group2"].push_back("Family2"); + + // write mesh + MEDFileUMesh * fileMesh = MEDFileUMesh::New(); + fileMesh->setMeshAtLevel(0, mesh); + fileMesh->setFamilyInfo(theFamilies); + fileMesh->setGroupInfo(theGroups); + fileMesh->setFamilyFieldArr(0, cellsFam); + fileMesh->write(fileName,2); + + cellsFam->decrRef(); + mesh ->decrRef(); + fileMesh->decrRef(); + + } // mesh creation + + // Partition the mesh into 4 parts + + const int ndomains = 4; + ParaDomainSelector parallelizer(false); + MeshCollection collection(fileName,parallelizer); + ParallelTopology* aPT = (ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + + std::auto_ptr< Topology > new_topo; +#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS) + new_topo.reset( collection.createPartition(ndomains,Graph::METIS) ); +#endif +#if defined(MED_ENABLE_SCOTCH) + if ( !new_topo.get() ) + new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) ); +#endif + if ( !new_topo.get() ) + return; + + // Check that "2D is available" + + const char xmlName[] = "tmp_testCreateBoundaryFaces2D"; + { + MyGlobals::_Creates_Boundary_Faces = true; + MeshCollection new_collection(collection,new_topo.get()); + + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); + CPPUNIT_ASSERT (new_collection.getNbOfLocalFaces() > 0 ); + + MyGlobals::_General_Informations.clear(); + MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D")); + new_collection.write( xmlName ); + } + + // Check that "groups and family handling is NOT bugged" + + MeshCollection new_collection(std::string(xmlName)+".xml"); + std::map< int, int > famId2nb; // count total nb of cells in divided families + std::map< int, int >::iterator id2nn; + { + const std::vector& famIdsVec = new_collection.getCellFamilyIds(); + for ( size_t i = 0; i < famIdsVec.size(); ++i ) + { + ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; + for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) + { + id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; + id2nn->second++; + } + } + } + CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0 )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 )); + CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]); + CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]); + CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]); + + // Check that "creates boundary faces option is handled" + + famId2nb.clear(); + const std::vector& famIdsVec = new_collection.getFaceFamilyIds(); + for ( size_t i = 0; i < famIdsVec.size(); ++i ) + { + ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; + for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) + { + id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; + id2nn->second++; + } + } + + CPPUNIT_ASSERT( !famId2nb.empty() ); + + // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group + // of the same size + std::map& famName2id = new_collection.getFamilyInfo(); + std::map::iterator na2id = famName2id.begin(), na2id2; + std::set< int > okFamIds; + okFamIds.insert(0); + for ( ; na2id != famName2id.end(); ++na2id ) + { + if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J') + continue; + na2id2 = na2id; + bool groupOK = false; + while ( !groupOK && ++na2id2 != famName2id.end() ) + groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos ); + + CPPUNIT_ASSERT( groupOK ); + CPPUNIT_ASSERT( na2id->second != na2id2->second); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second )); + CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ], + (int) famId2nb[ na2id->second ]); + okFamIds.insert( na2id2->second ); + } } diff --git a/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx b/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx index 5d1445ec8..d95ee9434 100644 --- a/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx +++ b/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx @@ -66,6 +66,8 @@ class MEDPARTITIONERTEST_EXPORT MEDPARTITIONERTest : public CppUnit::TestFixture #endif #endif + CPPUNIT_TEST( testCreateBoundaryFaces2D ); // imp 0021756 + //CPPUNIT_TEST( deleteTestMeshes ); CPPUNIT_TEST_SUITE_END(); @@ -133,6 +135,8 @@ public: void testMpirunMedianSize(); void testMpirunHugeSize(); #endif + + void testCreateBoundaryFaces2D(); }; #endif diff --git a/src/MEDPartitioner/Test/Makefile.am b/src/MEDPartitioner/Test/Makefile.am index 19dcc2283..b2a9420af 100644 --- a/src/MEDPartitioner/Test/Makefile.am +++ b/src/MEDPartitioner/Test/Makefile.am @@ -49,7 +49,7 @@ libMEDPARTITIONERTest_la_LDFLAGS= if MED_ENABLE_PARMETIS libMEDPARTITIONERTest_la_CPPFLAGS+= $(PARMETIS_CPPFLAGS) libMEDPARTITIONERTest_la_LDFLAGS+= $(PARMETIS_LIBS) -else +endif if MED_ENABLE_METIS libMEDPARTITIONERTest_la_CPPFLAGS += $(METIS_CPPFLAGS) libMEDPARTITIONERTest_la_LDFLAGS += $(METIS_LIBS) @@ -58,7 +58,6 @@ if MED_ENABLE_SCOTCH libMEDPARTITIONERTest_la_CPPFLAGS += $(SCOTCH_CPPFLAGS) libMEDPARTITIONERTest_la_LDFLAGS += $(SCOTCH_LIBS) endif -endif libMEDPARTITIONERTest_la_LDFLAGS += \ $(MED3_LIBS_C_ONLY) \ @@ -80,14 +79,13 @@ TestMEDPARTITIONER_CPPFLAGS = $(libMEDPARTITIONERTest_la_CPPFLAGS) \ if MPI_IS_OK TestMEDPARTITIONER_CPPFLAGS +=$(MPI_INCLUDES) $(PARMETIS_CPPFLAGS) -else +endif if MED_ENABLE_METIS TestMEDPARTITIONER_CPPFLAGS += $(METIS_CPPFLAGS) endif if MED_ENABLE_SCOTCH TestMEDPARTITIONER_CPPFLAGS += $(SCOTCH_CPPFLAGS) endif -endif TestMEDPARTITIONER_LDADD = \ $(libMEDPARTITIONERTest_la_LDFLAGS) -lm \ diff --git a/src/MEDPartitioner/medpartitioner.cxx b/src/MEDPartitioner/medpartitioner.cxx index 29073b76e..9dc2aad62 100644 --- a/src/MEDPartitioner/medpartitioner.cxx +++ b/src/MEDPartitioner/medpartitioner.cxx @@ -72,6 +72,7 @@ int main(int argc, char** argv) //sequential : no MPI MyGlobals::_World_Size=1; MyGlobals::_Rank=0; + MyGlobals::_Creates_Boundary_Faces=0; // Primitive parsing of command-line options string desc ("Available options of medpartitioner V1.0:\n" @@ -84,7 +85,7 @@ int main(int argc, char** argv) //user can choose! "\t--split-method= : name of the splitting library (metis/scotch), default is metis\n" #endif -// "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" + "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" ); @@ -109,7 +110,7 @@ int main(int argc, char** argv) else if (TestArg(argv[i],"--output-file",value)) output=value; else if (TestArg(argv[i],"--split-method",value)) library=value; else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); -// else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; + else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; else { @@ -149,7 +150,7 @@ int main(int argc, char** argv) cout << " output-file = " << output << endl; cout << " split-method = " << library << endl; cout << " ndomains = " << ndomains << endl; -// cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; + cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; cout << " dump-cpu-memory = " << mesure_memory<< endl; cout << " verbose = " << MyGlobals::_Verbose << endl; } diff --git a/src/ParaMEDMEM/ElementLocator.cxx b/src/ParaMEDMEM/ElementLocator.cxx index 8e15db02d..9709745d2 100644 --- a/src/ParaMEDMEM/ElementLocator.cxx +++ b/src/ParaMEDMEM/ElementLocator.cxx @@ -88,19 +88,19 @@ namespace ParaMEDMEM if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end()) return; - vector elems; + MEDCouplingAutoRefCountObjectPtr elems; #ifdef USE_DIRECTED_BB INTERP_KERNEL::DirectedBoundingBox dbb; double* distant_bb = _domain_bounding_boxes+rank*dbb.dataSize(_local_cell_mesh_space_dim); dbb.setData(distant_bb); - _local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment(),elems); + elems=_local_cell_mesh->getCellsInBoundingBox(dbb,getBoundingBoxAdjustment()); #else double* distant_bb = _domain_bounding_boxes+rank*2*_local_cell_mesh_space_dim; - _local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems); + elems=_local_cell_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment()); #endif DataArrayInt *distant_ids_send; - MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(&elems[0],&elems[elems.size()],distant_ids_send); + MEDCouplingPointSet *send_mesh = (MEDCouplingPointSet *)_local_para_field.getField()->buildSubMeshData(elems->begin(),elems->end(),distant_ids_send); _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids); distant_ids_send->decrRef(); diff --git a/src/ParaMEDMEM/OverlapElementLocator.cxx b/src/ParaMEDMEM/OverlapElementLocator.cxx index 417c50e0f..ab27b9273 100644 --- a/src/ParaMEDMEM/OverlapElementLocator.cxx +++ b/src/ParaMEDMEM/OverlapElementLocator.cxx @@ -270,7 +270,6 @@ namespace ParaMEDMEM */ void OverlapElementLocator::sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const { - vector elems; //int myProcId=_group.myRank(); const double *distant_bb=0; MEDCouplingPointSet *local_mesh=0; @@ -287,9 +286,9 @@ namespace ParaMEDMEM local_mesh=_local_target_mesh; field=_local_target_field; } - local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems); + MEDCouplingAutoRefCountObjectPtr elems=local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment()); DataArrayInt *idsToSend; - MEDCouplingPointSet *send_mesh=static_cast(field->getField()->buildSubMeshData(&elems[0],&elems[elems.size()],idsToSend)); + MEDCouplingPointSet *send_mesh=static_cast(field->getField()->buildSubMeshData(elems->begin(),elems->end(),idsToSend)); if(sourceOrTarget) matrix.keepTracksOfSourceIds(procId,idsToSend);//Case#1 in Step2 of main algorithm. else -- 2.39.2