From 0a5682a0e137feaa70bb56288e869eb0f59453c2 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 7 Apr 2011 09:43:18 +0000 Subject: [PATCH] Merge from PortingMED3 07Apr11 --- doc/MEDMEM/FIELDcreate.cxx | 5 +- doc/MEDMEM/FIELDcreate.py | 2 +- doc/MEDMEM/FIELDgeneral.cxx | 2 +- doc/MEDMEM/FIELDgeneral.py | 2 +- doc/MEDMEM/MEDMEM_Content.tex.in | 81 +- ...MEM_InvokingDriverAtObjectCreationTime.cxx | 3 - ...DMEM_InvokingDriverAtObjectCreationTime.py | 8 +- ..._InvokingDriverByAttachingItToAnObject.cxx | 18 - ...M_InvokingDriverByAttachingItToAnObject.py | 14 +- ...InvokingDriverFromStandardObjectMethod.cxx | 10 +- ..._InvokingDriverFromStandardObjectMethod.py | 6 +- .../MEDMEM_MedAddingAnExistingObject.cxx | 56 - doc/MEDMEM/MEDMEM_UsersGuide.lyx | 8 +- doc/MEDMEM/MESHINGexample.cxx | 29 +- doc/MEDMEM/MESHINGexample.py | 398 +--- doc/MEDMEM/MESHconnectivities.cxx | 75 +- doc/MEDMEM/MESHconnectivities.py | 51 +- doc/MEDMEM/Makefile.am | 1 - doc/doxygen/Doxyfile_med_user.in | 38 +- doc/doxygen/MED_class.dox | 24 - doc/doxygen/Makefile.am | 2 +- doc/doxygen/figures/OverlapDEC1.fig | 95 + doc/doxygen/figures/OverlapDEC1.png | Bin 0 -> 6982 bytes doc/doxygen/figures/UML_light.png | Bin 2803 -> 3990 bytes doc/doxygen/figures/UML_small.png | Bin 25901 -> 27022 bytes doc/doxygen/grid.dox | 13 +- doc/doxygen/medfilebrowser.dox | 22 + doc/doxygen/medmem.dox | 60 +- doc/doxygen/mesh.dox | 21 +- doc/doxygen/meshing.dox | 6 +- doc/doxygen/polygon.dox | 50 +- resources/Box1.med | Bin 26788 -> 26788 bytes resources/Box1Moderate.med | Bin 158788 -> 158788 bytes resources/Box2.med | Bin 26612 -> 26612 bytes resources/Box2Moderate.med | Bin 150100 -> 150100 bytes resources/Box3.med | Bin 27908 -> 27908 bytes resources/BoxEvenSmaller1.med | Bin 29476 -> 29476 bytes resources/BoxHexa1.med | Bin 34036 -> 34036 bytes resources/BoxHexa2.med | Bin 31124 -> 31124 bytes resources/BoxModSmall1.med | Bin 51924 -> 51924 bytes resources/BoxModSmall2.med | Bin 47956 -> 47956 bytes resources/BoxTetra2.med | Bin 28196 -> 28196 bytes resources/ComplexIncludedTetra.med | Bin 40140 -> 40140 bytes resources/ComplexIncludingTetra.med | Bin 41636 -> 41636 bytes resources/CornerTetra.med | Bin 25772 -> 25772 bytes resources/DegenEdgeXY.med | Bin 25772 -> 25772 bytes resources/DegenFaceXYZ.med | Bin 25772 -> 25772 bytes resources/DegenTranslatedInPlane.med | Bin 25772 -> 25772 bytes resources/DividedGenTetra1.med | Bin 57532 -> 57532 bytes resources/DividedGenTetra2.med | Bin 27380 -> 27380 bytes resources/DividedUnitTetra.med | Bin 26804 -> 26804 bytes resources/DividedUnitTetraSimpler.med | Bin 26060 -> 26060 bytes resources/GenTetra1.med | Bin 25836 -> 25836 bytes resources/GenTetra2.med | Bin 25836 -> 25836 bytes resources/GeneralTetra.med | Bin 25772 -> 25772 bytes resources/HalfstripOnly.med | Bin 25772 -> 25772 bytes resources/HalfstripOnly2.med | Bin 25772 -> 25772 bytes resources/LargeUnitTetra.med | Bin 25772 -> 25772 bytes resources/MovedHexaBox1.med | Bin 70308 -> 70308 bytes resources/MovedHexaBox2.med | Bin 48948 -> 48948 bytes resources/NudgedDividedUnitTetra.med | Bin 26804 -> 26804 bytes resources/NudgedDividedUnitTetraSimpler.med | Bin 26060 -> 26060 bytes resources/NudgedSimpler.med | Bin 25772 -> 25772 bytes resources/NudgedTetra.med | Bin 25772 -> 25772 bytes resources/SimpleHalfstripOnly.med | Bin 25772 -> 25772 bytes resources/SimpleIncludedTetra.med | Bin 25772 -> 25772 bytes resources/SimpleIncludingTetra.med | Bin 25772 -> 25772 bytes resources/TinyBox.med | Bin 26612 -> 26612 bytes resources/TrickyTetra1.med | Bin 25772 -> 25772 bytes resources/UnitTetra.med | Bin 25772 -> 25772 bytes resources/UnitTetraDegenT.med | Bin 25772 -> 25772 bytes resources/pointe.med | Bin 75776 -> 138252 bytes resources/polygones.med | Bin 83884 -> 83884 bytes .../Bases/InterpKernelException.hxx | 2 +- .../ExprEval/InterpKernelExprParser.cxx | 196 +- .../ExprEval/InterpKernelExprParser.hxx | 10 +- .../ExprEval/InterpKernelFunction.cxx | 58 + .../ExprEval/InterpKernelFunction.hxx | 24 + .../ExprEval/InterpKernelValue.cxx | 22 +- .../ExprEval/InterpKernelValue.hxx | 4 + .../InterpKernelGeo2DEdgeInfLin.hxx | 1 - src/INTERP_KERNEL/InterpolationUtils.hxx | 330 +++- src/INTERP_KERNEL/PlanarIntersector.txx | 2 +- src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx | 2 +- src/INTERP_KERNEL/PointLocatorAlgos.txx | 1 + src/INTERP_KERNEL/PolygonAlgorithms.txx | 10 +- src/INTERP_KERNELTest/ExprEvalInterpTest.cxx | 88 +- src/INTERP_KERNELTest/ExprEvalInterpTest.hxx | 2 + .../InterpolationOptionsTest.cxx | 4 +- src/INTERP_KERNELTest/MEDMeshMaker.cxx | 10 +- src/INTERP_KERNELTest/MeshTestToolkit.txx | 10 +- src/INTERP_KERNELTest/PointLocatorTest.cxx | 8 +- src/MEDCoupling/MEDCouplingCMesh.cxx | 88 +- src/MEDCoupling/MEDCouplingCMesh.hxx | 14 +- src/MEDCoupling/MEDCouplingExtrudedMesh.cxx | 15 + src/MEDCoupling/MEDCouplingExtrudedMesh.hxx | 3 + src/MEDCoupling/MEDCouplingFieldDouble.cxx | 8 + src/MEDCoupling/MEDCouplingMemArray.cxx | 111 +- src/MEDCoupling/MEDCouplingMemArray.hxx | 4 + src/MEDCoupling/MEDCouplingMesh.cxx | 12 + src/MEDCoupling/MEDCouplingMesh.hxx | 4 + .../MEDCouplingNormalizedUnstructuredMesh.txx | 4 +- src/MEDCoupling/MEDCouplingPointSet.cxx | 6 +- src/MEDCoupling/MEDCouplingPointSet.hxx | 5 +- src/MEDCoupling/MEDCouplingRemapper.cxx | 10 +- src/MEDCoupling/MEDCouplingRemapper.hxx | 2 + src/MEDCoupling/MEDCouplingUMesh.cxx | 189 +- src/MEDCoupling/MEDCouplingUMesh.hxx | 11 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 21 +- src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 9 +- .../Test/MEDCouplingBasicsTest.hxx | 11 +- .../Test/MEDCouplingBasicsTest4.cxx | 169 +- .../Test/MEDCouplingRemapperTest.cxx | 39 + .../Test/MEDCouplingRemapperTest.hxx | 2 + src/MEDCoupling/Test/TestMEDCoupling.cxx | 1 - .../Test/TestMEDCouplingRemapper.cxx | 1 - src/MEDCoupling_Swig/MEDCoupling.i | 199 +- src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 242 +++ .../MEDCouplingDataForTest.py | 28 + .../MEDCouplingRemapperTest.py | 48 + src/MEDLoader/MEDFileField.cxx | 313 ++-- src/MEDLoader/MEDFileField.hxx | 52 +- src/MEDLoader/MEDFileMesh.cxx | 1593 +++++++++++++---- src/MEDLoader/MEDFileMesh.hxx | 155 +- src/MEDLoader/MEDFileMeshElt.cxx | 128 +- src/MEDLoader/MEDFileMeshElt.hxx | 22 +- src/MEDLoader/MEDFileMeshLL.cxx | 451 +++-- src/MEDLoader/MEDFileMeshLL.hxx | 49 +- src/MEDLoader/MEDFileUtilities.cxx | 29 +- src/MEDLoader/MEDFileUtilities.hxx | 12 +- src/MEDLoader/MEDLoader.cxx | 1556 ++++++++-------- src/MEDLoader/MEDLoader.hxx | 12 +- src/MEDLoader/MEDLoaderBase.cxx | 26 + src/MEDLoader/MEDLoaderBase.hxx | 1 + src/MEDLoader/Makefile.am | 2 +- src/MEDLoader/Swig/MEDLoader.i | 286 ++- src/MEDLoader/Swig/MEDLoaderTest.py | 45 +- src/MEDLoader/Swig/MEDLoaderTest2.py | 33 +- src/MEDLoader/Swig/MEDLoaderTest3.py | 67 +- src/MEDLoader/Test/MEDLoaderTest.cxx | 48 +- src/ParaMEDMEM/OverlapDEC.cxx | 140 +- src/ParaMEDMEM/OverlapElementLocator.cxx | 15 +- src/ParaMEDMEM/OverlapElementLocator.hxx | 8 +- src/ParaMEDMEM/OverlapInterpolationMatrix.cxx | 129 +- src/ParaMEDMEM/OverlapInterpolationMatrix.hxx | 6 + src/ParaMEDMEM/OverlapMapping.cxx | 484 +++-- src/ParaMEDMEM/OverlapMapping.hxx | 37 +- src/ParaMEDMEMTest/ParaMEDMEMTest.hxx | 2 +- .../ParaMEDMEMTest_MEDLoader.cxx | 12 +- .../ParaMEDMEMTest_OverlapDEC.cxx | 26 +- src/RENUMBER/renumbering.cxx | 36 +- src/RENUMBER/testRenumbering.py | 168 +- 152 files changed, 6078 insertions(+), 3005 deletions(-) delete mode 100644 doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx delete mode 100644 doc/doxygen/MED_class.dox create mode 100644 doc/doxygen/figures/OverlapDEC1.fig create mode 100644 doc/doxygen/figures/OverlapDEC1.png create mode 100644 doc/doxygen/medfilebrowser.dox diff --git a/doc/MEDMEM/FIELDcreate.cxx b/doc/MEDMEM/FIELDcreate.cxx index 81b7acd47..393923c82 100644 --- a/doc/MEDMEM/FIELDcreate.cxx +++ b/doc/MEDMEM/FIELDcreate.cxx @@ -34,7 +34,6 @@ int main (int argc, char ** argv) { /* read MESH */ MESH * myMesh = new MESH(MED_DRIVER,MedFile,MeshName) ; - // myMesh->read() ; // we need a support : const SUPPORT * mySupport = myMesh->getSupportOnAll(MED_CELL); @@ -75,7 +74,7 @@ int main (int argc, char ** argv) { myField.setTime(Time) ; // Value : - int NumberOfValue = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int NumberOfValue = mySupport->getNumberOfElements(MEDMEM_ALL_ELEMENTS); for(int i=1; i<=NumberOfValue; i++) // i^th element for (int j=1; j<=NumberOfCompoennts; j++) { // j^th component double myValue = (i+j) * 0.1 ; @@ -83,7 +82,7 @@ int main (int argc, char ** argv) { } // save this new field - int id = myField.addDriver(MED_DRIVER) ; + myField.write(MED_DRIVER,filename) ; return 0 ; } diff --git a/doc/MEDMEM/FIELDcreate.py b/doc/MEDMEM/FIELDcreate.py index 944843076..ad0cbd2b0 100644 --- a/doc/MEDMEM/FIELDcreate.py +++ b/doc/MEDMEM/FIELDcreate.py @@ -66,7 +66,7 @@ myField.setOrderNumber(orderNumber) time = 3.435678 myField.setTime(time) -numberOfValue = mySupport.getNumberOfElements(MED_ALL_ELEMENTS) +numberOfValue = mySupport.getNumberOfElements(MEDMEM_ALL_ELEMENTS) for i in range(numberOfValue): ip1 = i+1 diff --git a/doc/MEDMEM/FIELDgeneral.cxx b/doc/MEDMEM/FIELDgeneral.cxx index 41a9bb52c..548baff96 100644 --- a/doc/MEDMEM/FIELDgeneral.cxx +++ b/doc/MEDMEM/FIELDgeneral.cxx @@ -68,7 +68,7 @@ int main (int argc, char ** argv) { " (and order number " << OrderNumber << ")" << endl ; // How many Value : - int NumberOfValue = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int NumberOfValue = mySupport->getNumberOfElements(MEDMEM_ALL_ELEMENTS); // Value const double * Value = myField.getValue(); for(int i=0; i myField (MED_DRIVER,fileName,fieldName); MESH myMesh (MED_DRIVER,fileName,meshName); - MED myMed (MED_DRIVER,fileName); // Test removal of drivers myField.rmDriver(); myMesh.rmDriver (); - myMed.rmDriver (); } catch (MEDEXCEPTION& ex){ MESSAGE_MED(ex.what()) ; diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py index d6c56cb89..939395bc1 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py @@ -37,15 +37,9 @@ try: print "Creation of MESH object" myMesh = MESH(MED_DRIVER,medFile,meshName) - print "Creation of MED object" - myMed = MED(MED_DRIVER,medFile) - - print "Test the driver removal dor MESH" + print "Test the driver removal for MESH" myMesh.rmDriver() - print "Test the driver removal dor MED" - myMed.rmDriver() - print "End of Python script" except: diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx index 624bc1b43..0197b43ed 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx @@ -25,8 +25,6 @@ #include "MEDMEM_Field.hxx" #include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMedDriver.hxx" #include "MEDMEM_MedMeshDriver.hxx" using namespace MEDMEM ; @@ -80,22 +78,6 @@ main () { delete myMesh; } - { - MED * myMed = new MED(); - MED_MED_RDONLY_DRIVER myRdOnlyDriver(fileName,myMed); - myRdOnlyDriver.open(); - myRdOnlyDriver.readFileStruct(); - myRdOnlyDriver.close(); - myMed->updateSupport(); // DOIT ETRE SUPPRIMEE - myRdOnlyDriver.read(); - // try { myRdOnlyDriver.write(); } catch (MEDEXCEPTION& ex) - // { MESSAGE(ex.what()); } - //MED_MED_WRONLY_DRIVER myWrOnlyDriver(fileName3,myMed); - //myWrOnlyDriver.open(); - //myWrOnlyDriver.write(); // Not implemented yet. - //myWrOnlyDriver.close(); - delete myMed; - } } catch (MEDEXCEPTION& ex){ cout << "MAIN BLOCK EXCEPTION" << endl; diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py index ea1316c7b..27f01397d 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py @@ -31,7 +31,7 @@ from libMEDMEM_Swig import * medFile = "pointe.med" medFile2 = "Field&MeshGeneratedPointe.med" -fieldName = "fieldcelldouble" +fieldName = "fieldcelldoublescalar" meshName = "maa1" try: @@ -71,15 +71,3 @@ except : print "there is a problem in invoking mesh drivers !!" print "Please consult the error standart output of the python execution !!" -try: - myMed = MED() - myRdOnlyDriver = MED_MED_RDONLY_DRIVER(medFile,myMed) - myRdOnlyDriver.open() - myRdOnlyDriver.readFileStruct() - myRdOnlyDriver.close() - myMed.updateSupport() - - print "Invoking Med drivers OK" -except : - print "There is a problem in invoking MED drivers !!" - print "Please consult the error standart output of the python execution !!" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx index 06fbfc65c..abb22db69 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx @@ -25,7 +25,6 @@ #include "MEDMEM_Field.hxx" #include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Med.hxx" using namespace MEDMEM ; using namespace MED_EN ; @@ -55,14 +54,9 @@ main () { myMesh->read(); myMesh->rmDriver(); - MED * myMed = new MED(); - int myDriver4 = myMed->addDriver(MED_DRIVER, fileName); - myMed->readFileStruct(); - myMed->rmDriver(); - delete myField; - delete myMesh; - delete myMed; + myMesh->removeReference(); + myField->removeReference(); } catch (MEDEXCEPTION& ex){ MESSAGE_MED(ex.what()) ; diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py index c1d870b51..52bcf2e90 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py @@ -31,7 +31,7 @@ from libMEDMEM_Swig import * medFile = "pointe.med" medFile2 = "fieldCellDoubleOfpointe.med" -fieldName = "fieldcelldouble" +fieldName = "fieldcelldoublescalar" meshName = "maa1" try: @@ -48,10 +48,6 @@ try: myMesh.read() myMesh.rmDriver() - myMed = MED(MED_DRIVER,medFile) - myMed.readFileStruct() - myMed.rmDriver() - except: print "There is a problem somewhere !!" print "Please consult the error standart output of the python execution !!" diff --git a/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx b/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx deleted file mode 100644 index e6258cc0c..000000000 --- a/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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 -// - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" - -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Med.hxx" - -main () { - - const char * fileName = "pointe.med"; - const char * fileName3 = "MedGeneratedPointe.med"; - const char * meshName1 = "maa1"; - const char * meshName2 = "maa1bis"; - - try { - - // FAIRE LE TEST AVEC LES CHAMPS AUSSI !. - - MESH* myMesh = new MESH(MED_DRIVER,fileName,meshName1); - myMesh->setName(meshName2); - myMesh->rmDriver(); - - MED myMed(MED_DRIVER,fileName); - myMed.read(); - myMed.addMesh(myMesh); - int myMedDriver = myMed.addDriver(MED_DRIVER,fileName3); - myMed.write(myMedDriver); - - // FAIRE LE TEST AVEC LES CHAMPS AUSSI !. - - } catch (MEDEXCEPTION& ex){ - MESSAGE_MED(ex.what()) ; - } -} diff --git a/doc/MEDMEM/MEDMEM_UsersGuide.lyx b/doc/MEDMEM/MEDMEM_UsersGuide.lyx index e0008ba8c..77a677e17 100644 --- a/doc/MEDMEM/MEDMEM_UsersGuide.lyx +++ b/doc/MEDMEM/MEDMEM_UsersGuide.lyx @@ -488,7 +488,7 @@ C++ Example\SpecialChar ~ \latex latex \backslash -verb+int NumberOfTriangle = myMesh.getNumberOfElements(MED_FACE,MED_TRIA3);+ +verb+int NumberOfTriangle = myMesh.getNumberOfElements(MED_FACE,MEDMEM_TRIA3);+ \layout Standard @@ -574,7 +574,7 @@ C++ Example\SpecialChar ~ \backslash begin{verbatim} \newline -int NumberOfTetrahedron = myMesh.getNumberOfElements(MED_CELL,MED_TETRA4); +int NumberOfTetrahedron = myMesh.getNumberOfElements(MED_CELL,MEDMEM_TETRA4); \newline int * TetrahedronConnectivity = \newline @@ -584,7 +584,7 @@ int * TetrahedronConnectivity = \newline MED_CELL, \newline - MED_TETRA4); + MEDMEM_TETRA4); \newline \backslash @@ -606,7 +606,7 @@ If you want to get connectivity of all elements (with \latex latex \backslash -verb+Type=MED_ALL_ELEMENTS+ +verb+Type=MEDMEM_ALL_ELEMENTS+ \latex default ), you must use the index array (return by \latex latex diff --git a/doc/MEDMEM/MESHINGexample.cxx b/doc/MEDMEM/MESHINGexample.cxx index 737d976e9..3c85ce73e 100644 --- a/doc/MEDMEM/MESHINGexample.cxx +++ b/doc/MEDMEM/MESHINGexample.cxx @@ -75,7 +75,7 @@ int main (int argc, char ** argv) { // cell part const int NumberOfTypes = 3 ; - medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8} ; + medGeometryElement Types[NumberOfTypes] = {MEDMEM_TETRA4,MEDMEM_PYRA5,MEDMEM_HEXA8} ; const int NumberOfElements[NumberOfTypes] = {12,2,2} ; myMeshing->setNumberOfTypes(NumberOfTypes,MED_CELL); @@ -99,7 +99,7 @@ int main (int argc, char ** argv) { 2,10,6,9 }; - myMeshing->setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4); + myMeshing->setConnectivity(MED_CELL,MEDMEM_TETRA4,ConnectivityTetra); int ConnectivityPyra[2*5]= { @@ -107,7 +107,7 @@ int main (int argc, char ** argv) { 15,18,17,16,19 }; - myMeshing->setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5); + myMeshing->setConnectivity(MED_CELL,MEDMEM_PYRA5,ConnectivityPyra); int ConnectivityHexa[2*8]= { @@ -115,12 +115,12 @@ int main (int argc, char ** argv) { 15,16,17,18,11,12,13,14 }; - myMeshing->setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8); + myMeshing->setConnectivity(MED_CELL,MEDMEM_HEXA8,ConnectivityHexa); // face part const int NumberOfFacesTypes = 2 ; - medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4} ; + medGeometryElement FacesTypes[NumberOfFacesTypes] = {MEDMEM_TRIA3,MEDMEM_QUAD4} ; const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4} ; myMeshing->setNumberOfTypes(NumberOfFacesTypes,MED_FACE); @@ -136,7 +136,7 @@ int main (int argc, char ** argv) { 1,3,6 }; - myMeshing->setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3); + myMeshing->setConnectivity(MED_FACE,MEDMEM_TRIA3,ConnectivityTria); int ConnectivityQua[4*4]= { @@ -146,7 +146,7 @@ int main (int argc, char ** argv) { 12,8,9,13 }; - myMeshing->setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4); + myMeshing->setConnectivity(MED_FACE,MEDMEM_QUAD4,ConnectivityQua); // edge part @@ -161,7 +161,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_NODE); myGroup->setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; + medGeometryElement myTypes[1] = {MEDMEM_NONE}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[1] = {4} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -178,7 +178,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_NODE); myGroup->setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; + medGeometryElement myTypes[1] = {MEDMEM_NONE}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[1] = {3} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -197,7 +197,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_CELL); myGroup->setNumberOfGeometricType(3); - medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + medGeometryElement myTypes[3] = {MEDMEM_TETRA4,MEDMEM_PYRA5,MEDMEM_HEXA8}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[3] = {4,1,2} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -219,7 +219,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_CELL); myGroup->setNumberOfGeometricType(2); - medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; + medGeometryElement myTypes[] = {MEDMEM_TETRA4,MEDMEM_PYRA5}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[] = {4,1} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -242,7 +242,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_FACE); myGroup->setNumberOfGeometricType(2); - medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; + medGeometryElement myTypes[2] = {MEDMEM_TRIA3,MEDMEM_QUAD4}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[2] = {2,3} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -263,7 +263,7 @@ int main (int argc, char ** argv) { myGroup->setMesh(myMeshing); myGroup->setEntity(MED_FACE); myGroup->setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_TRIA3}; + medGeometryElement myTypes[1] = {MEDMEM_TRIA3}; myGroup->setGeometricType(myTypes); const int myNumberOfElements[1] = {2} ; myGroup->setNumberOfElements(myNumberOfElements); @@ -282,6 +282,5 @@ int main (int argc, char ** argv) { int id = myMeshing->addDriver(MED_DRIVER,filename,myMeshing->getName()); myMeshing->write(id) ; - + myMeshing->removeReference(); } - diff --git a/doc/MEDMEM/MESHINGexample.py b/doc/MEDMEM/MESHINGexample.py index 77694b2fc..21e616a8c 100644 --- a/doc/MEDMEM/MESHINGexample.py +++ b/doc/MEDMEM/MESHINGexample.py @@ -49,84 +49,26 @@ spaceDimension = 3 numberOfNodes = 19 -coordinates = [] - -coordinate = [0.0, 0.0, 0.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [0.0, 0.0, 1.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [2.0, 0.0, 1.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [0.0, 2.0, 1.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-2.0, 0.0, 1.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [0.0, -2.0, 1.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, 1.0, 2.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, 1.0, 2.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, -1.0, 2.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, -1.0, 2.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, 1.0, 3.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, 1.0, 3.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, -1.0, 3.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, -1.0, 3.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, 1.0, 4.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, 1.0, 4.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [-1.0, -1.0, 4.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [1.0, -1.0, 4.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) -coordinate = [0.0, 0.0, 5.0] -coordinates.append(coordinate[0]) -coordinates.append(coordinate[1]) -coordinates.append(coordinate[2]) +coordinates = [ + 0.0, 0.0, 0.0 , + 0.0, 0.0, 1.0 , + 2.0, 0.0, 1.0 , + 0.0, 2.0, 1.0 , + -2.0, 0.0, 1.0 , + 0.0, -2.0, 1.0 , + 1.0, 1.0, 2.0 , + -1.0, 1.0, 2.0 , + -1.0, -1.0, 2.0, + 1.0, -1.0, 2.0 , + 1.0, 1.0, 3.0 , + -1.0, 1.0, 3.0 , + -1.0, -1.0, 3.0, + 1.0, -1.0, 3.0 , + 1.0, 1.0, 4.0 , + -1.0, 1.0, 4.0 , + -1.0, -1.0, 4.0, + 1.0, -1.0, 4.0 , + 0.0, 0.0, 5.0] myMeshing.setCoordinates(spaceDimension,numberOfNodes,coordinates,"CARTESIAN",MED_FULL_INTERLACE) @@ -151,121 +93,46 @@ entity = MED_CELL types = [] numberOfElements = [] -types.append(MED_TETRA4) +types.append(MEDMEM_TETRA4) numberOfElements.append(12) -types.append(MED_PYRA5) +types.append(MEDMEM_PYRA5) numberOfElements.append(2) -types.append(MED_HEXA8) +types.append(MEDMEM_HEXA8) numberOfElements.append(2) myMeshing.setNumberOfTypes(numberOfTypes,entity) myMeshing.setTypes(types,entity) myMeshing.setNumberOfElements(numberOfElements,entity) -connectivityTetra = [] - -connectivity = [1,2,3,6] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [1,2,4,3] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [1,2,5,4] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [1,2,6,5] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,7,4,3] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,8,5,4] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,9,6,5] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,10,3,6] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,7,3,10] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,8,4,7] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,9,5,8] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) -connectivity = [2,10,6,9] -connectivityTetra.append(connectivity[0]) -connectivityTetra.append(connectivity[1]) -connectivityTetra.append(connectivity[2]) -connectivityTetra.append(connectivity[3]) - -myMeshing.setConnectivity(connectivityTetra,entity,types[0]) - -connectivityPyra = [] -connectivity = [7,8,9,10,2] -connectivityPyra.append(connectivity[0]) -connectivityPyra.append(connectivity[1]) -connectivityPyra.append(connectivity[2]) -connectivityPyra.append(connectivity[3]) -connectivityPyra.append(connectivity[4]) -connectivity = [15,18,17,16,19] -connectivityPyra.append(connectivity[0]) -connectivityPyra.append(connectivity[1]) -connectivityPyra.append(connectivity[2]) -connectivityPyra.append(connectivity[3]) -connectivityPyra.append(connectivity[4]) - -myMeshing.setConnectivity(connectivityPyra,entity,types[1]) - -connectivityHexa = [] -connectivity = [11,12,13,14,7,8,9,10] -connectivityHexa.append(connectivity[0]) -connectivityHexa.append(connectivity[1]) -connectivityHexa.append(connectivity[2]) -connectivityHexa.append(connectivity[3]) -connectivityHexa.append(connectivity[4]) -connectivityHexa.append(connectivity[5]) -connectivityHexa.append(connectivity[6]) -connectivityHexa.append(connectivity[7]) -connectivity = [15,16,17,18,11,12,13,14] -connectivityHexa.append(connectivity[0]) -connectivityHexa.append(connectivity[1]) -connectivityHexa.append(connectivity[2]) -connectivityHexa.append(connectivity[3]) -connectivityHexa.append(connectivity[4]) -connectivityHexa.append(connectivity[5]) -connectivityHexa.append(connectivity[6]) -connectivityHexa.append(connectivity[7]) - -myMeshing.setConnectivity(connectivityHexa,entity,types[2]) +connectivityTetra = [ + 1,2,3,6 , + 1,2,4,3 , + 1,2,5,4 , + 1,2,6,5 , + 2,7,4,3 , + 2,8,5,4 , + 2,9,6,5 , + 2,10,3,6, + 2,7,3,10, + 2,8,4,7 , + 2,9,5,8 , + 2,10,6,9] + +myMeshing.setConnectivity(entity,types[0],connectivityTetra) + +connectivityPyra = [ + 7,8,9,10,2, + 15,18,17,16,19] + +myMeshing.setConnectivity(entity,types[1],connectivityPyra) + +connectivityHexa = [ + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14] + +myMeshing.setConnectivity(entity,types[2],connectivityPyra) # face part @@ -275,62 +142,31 @@ entity = MED_FACE types = [] numberOfElements = [] -types.append(MED_TRIA3) +types.append(MEDMEM_TRIA3) numberOfElements.append(4) -types.append(MED_QUAD4) +types.append(MEDMEM_QUAD4) numberOfElements.append(4) myMeshing.setNumberOfTypes(numberOfTypes,entity) myMeshing.setTypes(types,entity) myMeshing.setNumberOfElements(numberOfElements,entity) -connectivityTria = [] -connectivity = [1,4,3] -connectivityTria.append(connectivity[0]) -connectivityTria.append(connectivity[1]) -connectivityTria.append(connectivity[2]) -connectivity = [1,5,4] -connectivityTria.append(connectivity[0]) -connectivityTria.append(connectivity[1]) -connectivityTria.append(connectivity[2]) -connectivity = [1,6,5] -connectivityTria.append(connectivity[0]) -connectivityTria.append(connectivity[1]) -connectivityTria.append(connectivity[2]) -connectivity = [1,3,6] -connectivityTria.append(connectivity[0]) -connectivityTria.append(connectivity[1]) -connectivityTria.append(connectivity[2]) - -myMeshing.setConnectivity(connectivityTria,entity,types[0]) - -connectivityQuad = [] -connectivity = [7,8,9,10] -connectivityQuad.append(connectivity[0]) -connectivityQuad.append(connectivity[1]) -connectivityQuad.append(connectivity[2]) -connectivityQuad.append(connectivity[3]) -connectivity = [11,12,13,14] -connectivityQuad.append(connectivity[0]) -connectivityQuad.append(connectivity[1]) -connectivityQuad.append(connectivity[2]) -connectivityQuad.append(connectivity[3]) -connectivity = [11,7,8,12] -connectivityQuad.append(connectivity[0]) -connectivityQuad.append(connectivity[1]) -connectivityQuad.append(connectivity[2]) -connectivityQuad.append(connectivity[3]) -connectivity = [12,8,9,13] -connectivityQuad.append(connectivity[0]) -connectivityQuad.append(connectivity[1]) -connectivityQuad.append(connectivity[2]) -connectivityQuad.append(connectivity[3]) - -myMeshing.setConnectivity(connectivityQuad,entity,types[1]) - -meshDimension = spaceDimension # because there 3D cells in the mesh -myMeshing.setMeshDimension(meshDimension) +connectivityTria = [ + 1,4,3, + 1,5,4, + 1,6,5, + 1,3,6] + +myMeshing.setConnectivity(entity,types[0],connectivityPyra) + +connectivityQuad = [ + 7,8,9,10 , + 11,12,13,14, + 11,7,8,12 , + 12,8,9,13] + +myMeshing.setConnectivity(entity,types[1],connectivityQuad) # edge part @@ -343,7 +179,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_NODE) myGroup.setNumberOfGeometricType(1) -myTypes = [MED_NONE] +myTypes = [MEDMEM_NONE] myGroup.setGeometricType(myTypes) myNumberOfElements = [4] @@ -361,7 +197,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_NODE) myGroup.setNumberOfGeometricType(1) -myTypes = [MED_NONE] +myTypes = [MEDMEM_NONE] myGroup.setGeometricType(myTypes) myNumberOfElements = [3] @@ -381,7 +217,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_CELL) myGroup.setNumberOfGeometricType(3) -myTypes = [MED_TETRA4,MED_PYRA5,MED_HEXA8] +myTypes = [MEDMEM_TETRA4,MEDMEM_PYRA5,MEDMEM_HEXA8] myGroup.setGeometricType(myTypes) myNumberOfElements = [4,1,2] @@ -403,7 +239,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_CELL) myGroup.setNumberOfGeometricType(2) -myTypes = [MED_TETRA4,MED_PYRA5] +myTypes = [MEDMEM_TETRA4,MEDMEM_PYRA5] myGroup.setGeometricType(myTypes) myNumberOfElements = [4,1] @@ -426,7 +262,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_FACE) myGroup.setNumberOfGeometricType(2) -myTypes = [MED_TRIA3,MED_QUAD4] +myTypes = [MEDMEM_TRIA3,MEDMEM_QUAD4] myGroup.setGeometricType(myTypes) myNumberOfElements = [2,3] @@ -447,7 +283,7 @@ myGroup.setMesh(myMeshing) myGroup.setEntity(MED_FACE) myGroup.setNumberOfGeometricType(1) -myTypes = [MED_TRIA3] +myTypes = [MEDMEM_TRIA3] myGroup.setGeometricType(myTypes) myNumberOfElements = [2] @@ -461,36 +297,21 @@ myGroup.setNumber(index,values) myMeshing.addGroup(myGroup) -# saving of the generated mesh in MED 2.1, 2.2 and VTK format +# saving of the generated mesh in MED and VTK format -medFileVersion = getMedFileVersionForWriting() -print "Med File Version For Writing ",medFileVersion +myMeshing.write(MED_DRIVER,med22FileName) -if (medFileVersion == V22): - setMedFileVersionForWriting(V21) - -idMedV21 = myMeshing.addDriver(MED_DRIVER,med21FileName,myMeshing.getName()) -myMeshing.write(idMedV21) - -medFileVersion = getMedFileVersionForWriting() -if (medFileVersion == V21): - setMedFileVersionForWriting(V22) - -idMedV22 = myMeshing.addDriver(MED_DRIVER,med22FileName,myMeshing.getName()) -myMeshing.write(idMedV22) - -idVtk = myMeshing.addDriver(VTK_DRIVER,vtkFileName,myMeshing.getName()) -myMeshing.write(idVtk) +myMeshing.write(VTK_DRIVER,vtkFileName) # we build now 8 fields : 4 fields double (integer) : # 2 fields on nodes (cells) : # 1 scalar (vector) supportOnNodes = myMeshing.getSupportOnAll(MED_NODE) -numberOfNodes = supportOnNodes.getNumberOfElements(MED_ALL_ELEMENTS) +numberOfNodes = supportOnNodes.getNumberOfElements(MEDMEM_ALL_ELEMENTS) supportOnCells = myMeshing.getSupportOnAll(MED_CELL) -numberOfCells = supportOnCells.getNumberOfElements(MED_ALL_ELEMENTS) +numberOfCells = supportOnCells.getNumberOfElements(MEDMEM_ALL_ELEMENTS) fieldDoubleScalarOnNodes = FIELDDOUBLE(supportOnNodes,1) fieldDoubleScalarOnNodes.setName("fieldScalarDoubleNode") @@ -634,63 +455,14 @@ for i in range(numberOfCells): fieldIntVectorOnCells.setValueIJ(i+1,2,valueInt2) fieldIntVectorOnCells.setValueIJ(i+1,3,valueInt3) -medFileVersion = getMedFileVersionForWriting() -print "Med File Version For Writing ",medFileVersion - -if (medFileVersion == V22): - setMedFileVersionForWriting(V21) - -idMedV21 = fieldDoubleScalarOnNodes.addDriver(MED_DRIVER,med21FileName,fieldDoubleScalarOnNodes.getName()) -fieldDoubleScalarOnNodes.write(idMedV21) - -idMedV21 = fieldIntScalarOnNodes.addDriver(MED_DRIVER,med21FileName,fieldIntScalarOnNodes.getName()) -fieldIntScalarOnNodes.write(idMedV21) - -idMedV21 = fieldDoubleVectorOnNodes.addDriver(MED_DRIVER,med21FileName,fieldDoubleVectorOnNodes.getName()) -fieldDoubleVectorOnNodes.write(idMedV21) - -idMedV21 = fieldIntVectorOnNodes.addDriver(MED_DRIVER,med21FileName,fieldIntVectorOnNodes.getName()) -fieldIntVectorOnNodes.write(idMedV21) - -idMedV21 = fieldDoubleScalarOnCells.addDriver(MED_DRIVER,med21FileName,fieldDoubleScalarOnCells.getName()) -fieldDoubleScalarOnCells.write(idMedV21) - -idMedV21 = fieldIntScalarOnCells.addDriver(MED_DRIVER,med21FileName,fieldIntScalarOnCells.getName()) -fieldIntScalarOnCells.write(idMedV21) - -idMedV21 = fieldDoubleVectorOnCells.addDriver(MED_DRIVER,med21FileName,fieldDoubleVectorOnCells.getName()) -fieldDoubleVectorOnCells.write(idMedV21) - -idMedV21 = fieldIntVectorOnCells.addDriver(MED_DRIVER,med21FileName,fieldIntVectorOnCells.getName()) -fieldIntVectorOnCells.write(idMedV21) - -medFileVersion = getMedFileVersionForWriting() -if (medFileVersion == V21): - setMedFileVersionForWriting(V22) - -idMedV22 = fieldDoubleScalarOnNodes.addDriver(MED_DRIVER,med22FileName,fieldDoubleScalarOnNodes.getName()) -fieldDoubleScalarOnNodes.write(idMedV22) - -idMedV22 = fieldIntScalarOnNodes.addDriver(MED_DRIVER,med22FileName,fieldIntScalarOnNodes.getName()) -fieldIntScalarOnNodes.write(idMedV22) - -idMedV22 = fieldDoubleVectorOnNodes.addDriver(MED_DRIVER,med22FileName,fieldDoubleVectorOnNodes.getName()) -fieldDoubleVectorOnNodes.write(idMedV22) - -idMedV22 = fieldIntVectorOnNodes.addDriver(MED_DRIVER,med22FileName,fieldIntVectorOnNodes.getName()) -fieldIntVectorOnNodes.write(idMedV22) - -idMedV22 = fieldDoubleScalarOnCells.addDriver(MED_DRIVER,med22FileName,fieldDoubleScalarOnCells.getName()) -fieldDoubleScalarOnCells.write(idMedV22) - -idMedV22 = fieldIntScalarOnCells.addDriver(MED_DRIVER,med22FileName,fieldIntScalarOnCells.getName()) -fieldIntScalarOnCells.write(idMedV22) - -idMedV22 = fieldDoubleVectorOnCells.addDriver(MED_DRIVER,med22FileName,fieldDoubleVectorOnCells.getName()) -fieldDoubleVectorOnCells.write(idMedV22) +fieldIntScalarOnNodes.write(MED_DRIVER,med21FileName) +fieldDoubleVectorOnNodes.write(MED_DRIVER,med21FileName) +fieldIntVectorOnNodes.write(MED_DRIVER,med21FileName) +fieldDoubleScalarOnCells.write(MED_DRIVER,med21FileName) +fieldIntScalarOnCells.write(MED_DRIVER,med21FileName) +fieldDoubleVectorOnCells.write(MED_DRIVER,med21FileName) +fieldIntVectorOnCells.addDriver(MED_DRIVER,med21FileName) -idMedV22 = fieldIntVectorOnCells.addDriver(MED_DRIVER,med22FileName,fieldIntVectorOnCells.getName()) -fieldIntVectorOnCells.write(idMedV22) idVtk = fieldDoubleScalarOnNodes.addDriver(VTK_DRIVER,vtkFileName,fieldDoubleScalarOnNodes.getName()) fieldDoubleScalarOnNodes.writeAppend(idVtk) diff --git a/doc/MEDMEM/MESHconnectivities.cxx b/doc/MEDMEM/MESHconnectivities.cxx index dee9539b5..8edffe2a2 100644 --- a/doc/MEDMEM/MESHconnectivities.cxx +++ b/doc/MEDMEM/MESHconnectivities.cxx @@ -25,16 +25,15 @@ using namespace MEDMEM ; using namespace MED_EN ; -int main (int argc, char ** argv) { - -// const string MedFile = "polyedres.med" ; -// const string MeshName = "Erreur orientation" ; -// const string MedFile = "polygones.med" ; -// const string MeshName = "Bord" ; +int main (int argc, char ** argv) +{ + // const string MedFile = "polyedres.med" ; + // const string MeshName = "Erreur orientation" ; + // const string MedFile = "polygones.med" ; + // const string MeshName = "Bord" ; const string MedFile = "pointe.med" ; const string MeshName = "maa1" ; MESH myMesh(MED_DRIVER,MedFile,MeshName) ; - myMesh.read() ; cout << "Mesh name : " << myMesh.getName() << endl << endl ; @@ -49,11 +48,7 @@ int main (int argc, char ** argv) { medGeometryElement myType = Types[i] ; int NumberOfElements = myMesh.getNumberOfElements(MED_CELL,myType); int NomberOfNodesPerCell = Types[i]%100 ; - const int * Connectivity = - myMesh.getConnectivity(MED_FULL_INTERLACE, - MED_NODAL, - MED_CELL, - myType); + const int * Connectivity = myMesh.getConnectivity(MED_NODAL,MED_CELL,myType); for (int j=0; j 0 ) - { - cout << "Show Connectivity (Nodal) of POLYGONS:" << endl ; - const int* Connectivity = myMesh.getPolygonsConnectivity(MED_NODAL,MED_CELL); - const int* ConnectivityIndex = myMesh.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL); - for (int j=0; j 0 ) - { - cout << "Show Connectivity (Nodal) of POLYHEDRONS:" << endl ; - const int* Connectivity = myMesh.getPolyhedronConnectivity(MED_NODAL); - const int* FaceIndex = myMesh.getPolyhedronFacesIndex(); - const int* Index = myMesh.getPolyhedronIndex(MED_NODAL); - for (int j=0; j 0 : - print "" - print " Show Connectivity (Nodal) of POLYGONS:" - print "" - connectivity = myMesh.getPolygonsConnectivity(MED_NODAL,MED_CELL) - index = myMesh.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL) - for j in range(nbPolygons): - print " Polygon",(j+1)," ",connectivity[ index[j]-1 : index[j+1]-1 ] - pass - pass - -nbPolyhedrons = myMesh.getNumberOfPolyhedron() -if nbPolyhedrons > 0 : - print "" - print " Show Connectivity (Nodal) of POLYHEDRONS:" - print "" - connectivity = myMesh.getPolyhedronConnectivity(MED_NODAL) - fIndex = myMesh.getPolyhedronFacesIndex() - index = myMesh.getPolyhedronIndex(MED_NODAL) - for j in range(nbPolyhedrons): - print " Polyhedra",(j+1) - iF1, iF2 = index[ j ]-1, index[ j+1 ]-1 - for f in range( iF2 - iF1 ): - iN1, iN2 = fIndex[ iF1+f ]-1, fIndex[ iF1+f+1 ]-1 - print " Face",f+1," ",connectivity[ iN1 : iN2 ] - pass - pass - pass diff --git a/doc/MEDMEM/Makefile.am b/doc/MEDMEM/Makefile.am index 068211be4..0708300b6 100644 --- a/doc/MEDMEM/Makefile.am +++ b/doc/MEDMEM/Makefile.am @@ -31,7 +31,6 @@ EXTRA_DIST += \ MEDMEM_InvokingDriverByAttachingItToAnObject.py \ MEDMEM_InvokingDriverFromStandardObjectMethod.cxx \ MEDMEM_InvokingDriverFromStandardObjectMethod.py \ - MEDMEM_MedAddingAnExistingObject.cxx \ MEDMEM_UsersGuide.lyx \ MESHconnectivities.cxx \ MESHconnectivities.py \ diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in index f8e39d1f8..ceb855b61 100644 --- a/doc/doxygen/Doxyfile_med_user.in +++ b/doc/doxygen/Doxyfile_med_user.in @@ -77,13 +77,15 @@ INPUT = @srcdir@ \ @srcdir@/../../src/MEDLoader \ @srcdir@/../../src/MEDMEM -FILE_PATTERNS = MEDMEM_Mesh.* \ +FILE_PATTERNS = MEDMEM_GMesh.* \ + MEDMEM_Mesh.* \ MEDMEM_Grid.* \ MEDMEM_Meshing.* \ MEDMEM_Support.* \ MEDMEM_Field.* \ - MEDMEM_Med.* \ + MEDMEM_MedFileBrowser.* \ InterpKernelDEC.* \ + OverlapDEC.* \ DEC.* \ MPIProcessorGroup.* \ StructuredCoincidentDEC.* \ @@ -108,28 +110,30 @@ FILE_PATTERNS = MEDMEM_Mesh.* \ InterpKernelGeo2DNode.* \ InterpKernelGeo2DQuadraticPolygon.* \ ParaFIELD.* \ - MEDCouplingMesh.* \ + MEDCouplingMesh.* \ MEDCouplingUMesh.* \ - MEDCouplingUMeshDesc.* \ - MEDCouplingPointSet.* \ - MEDCouplingCMesh.* \ - MEDCouplingExtrudedMesh.* \ - MEDCouplingFieldDouble.* \ - MEDCouplingField.* \ - MEDCouplingFieldDiscretization.* \ - MEDCouplingTimeDiscretization.* \ - MEDCouplingTimeLabel.* \ - MEDCouplingRefCountObject.* \ - MEDCouplingMemArray.* \ - MEDCouplingRemapper.* \ - MEDLoader.* \ - MEDFileMesh.* \ + MEDCouplingUMeshDesc.* \ + MEDCouplingPointSet.* \ + MEDCouplingCMesh.* \ + MEDCouplingExtrudedMesh.* \ + MEDCouplingFieldDouble.* \ + MEDCouplingField.* \ + MEDCouplingFieldTemplate.* \ + MEDCouplingFieldDiscretization.* \ + MEDCouplingTimeDiscretization.* \ + MEDCouplingTimeLabel.* \ + MEDCouplingRefCountObject.* \ + MEDCouplingMemArray.* \ + MEDCouplingRemapper.* \ + MEDLoader.* \ + MEDFileMesh.* \ *.dox RECURSIVE = NO EXCLUDE = CVS EXCLUDE_PATTERNS = *~ EXAMPLE_PATH = @srcdir@/../../src/ParaMEDMEM/ \ @srcdir@/../../doc/MEDMEM \ + @srcdir@/../../src/MEDMEMBinTest \ @srcdir@/../../src/MEDMEM EXAMPLE_PATTERNS = *.cxx *.py EXAMPLE_RECURSIVE = NO diff --git a/doc/doxygen/MED_class.dox b/doc/doxygen/MED_class.dox deleted file mode 100644 index fa348a573..000000000 --- a/doc/doxygen/MED_class.dox +++ /dev/null @@ -1,24 +0,0 @@ - -/*! -\page MED_class MED object - -\section MED_general General Information - -This object is used to give information about the different -meshes/supports/fields that are contained in a file. -This enables the user to know about the file content without -loading the meshes in memory. Also, it can be useful for -memory management since meshes, supports and fields accessed through a MED -object are destroyed when the MED object is destroyed. - -\section MED_object_outline -The methods are described in the following sections : -- constructors : \ref MED_constructors -- query methods : \ref MED_query - -For an example using these methods, one may see the Python scripts in the -directory \c $MED_ROOT_DIR/bin/salome/,\c testMedObj.py, or C++ -example program in the directory \c $MED_SRC_DIR/src/MEDMEM, -\c duplicateMED.cxx. - -*/ \ No newline at end of file diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am index 1006765c8..e2d592805 100644 --- a/doc/doxygen/Makefile.am +++ b/doc/doxygen/Makefile.am @@ -46,7 +46,6 @@ clean-local: EXTRA_DIST += figures \ main.dox \ Geometric2D.dox \ - MED_class.dox \ biblio.dox \ barycoords.dox \ dualmesh.dox \ @@ -55,6 +54,7 @@ EXTRA_DIST += figures \ grid.dox \ interpkernel.dox \ medcoupling.dox \ + medfilebrowser.dox \ medloader.dox \ medmem.dox \ medsplitter.dox \ diff --git a/doc/doxygen/figures/OverlapDEC1.fig b/doc/doxygen/figures/OverlapDEC1.fig new file mode 100644 index 000000000..31166cd1e --- /dev/null +++ b/doc/doxygen/figures/OverlapDEC1.fig @@ -0,0 +1,95 @@ +#FIG 3.2 Produced by xfig version 3.2.5b +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 5775 5775 6750 6600 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6450 5850 6750 5850 +2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6450 6450 6750 6450 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6450 6150 6750 6150 +4 0 0 50 -1 0 12 0.0000 4 180 525 5775 5925 proc 0\001 +4 0 2 50 -1 0 12 0.0000 4 180 525 5775 6525 proc 2\001 +4 0 1 50 -1 0 12 0.0000 4 180 525 5775 6225 proc 1\001 +-6 +6 2700 4050 3150 4500 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2925 4275 212 212 2925 4275 3075 4425 +4 0 0 50 -1 0 14 0.0000 4 165 120 2925 4350 0\001 +-6 +6 9300 3825 9750 4275 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 9525 4050 212 212 9525 4050 9675 4200 +4 0 0 50 -1 0 14 0.0000 4 165 120 9525 4125 0\001 +-6 +6 4275 3525 4725 3975 +1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 4500 3750 212 212 4500 3750 4712 3750 +4 0 1 50 -1 0 12 0.0000 4 135 105 4425 3825 0\001 +-6 +6 7950 3225 8400 3675 +1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 8175 3450 212 212 8175 3450 8387 3450 +4 0 1 50 -1 0 12 0.0000 4 135 105 8100 3525 0\001 +-6 +6 2775 2550 3225 3000 +1 3 0 1 2 7 50 -1 -1 0.000 1 0.0000 3000 2775 212 212 3000 2775 3212 2775 +4 0 2 50 -1 0 12 0.0000 4 135 105 3000 2850 0\001 +-6 +6 8775 2475 9225 2925 +1 3 0 1 2 7 50 -1 -1 0.000 1 0.0000 9000 2700 212 212 9000 2700 9212 2700 +4 0 2 50 -1 0 12 0.0000 4 135 105 9000 2775 0\001 +-6 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3975 4425 212 212 3975 4425 4125 4575 +1 3 0 1 1 7 50 -1 -1 0.000 1 0.0000 4248 2814 212 212 4248 2814 4460 2814 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 + 3600 3600 4800 4800 3600 4800 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3600 4800 2400 4800 2400 3600 3600 3600 3600 4800 +2 2 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4875 3375 3675 3375 3675 2175 4875 2175 4875 3375 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 3 + 4875 3375 4875 4650 3675 3375 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6225 5250 6225 975 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3075 1425 3975 1425 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 8700 1425 9525 1425 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7800 4800 10200 4800 10200 2400 7800 4800 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7800 4650 8925 3525 7800 2475 7800 4650 +2 1 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 9000 3450 10125 2325 7875 2325 9000 3450 +2 2 0 1 2 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3600 3375 2400 3375 2400 2175 3600 2175 3600 3375 +4 0 0 50 -1 0 12 0.0000 4 135 105 2325 5100 0\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 4725 5100 2\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 3600 5100 1\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 2175 3750 3\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 3450 3825 4\001 +4 0 0 50 -1 0 20 0.0000 4 225 930 3075 1275 Source\001 +4 0 0 50 -1 0 14 0.0000 4 165 120 3900 4500 1\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 2175 3450 0\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 3450 3300 1\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 3825 3300 1\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 5025 3375 2\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 3750 2025 3\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 4950 2025 4\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 4950 4875 0\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 4200 2850 1\001 +4 0 0 50 -1 0 20 0.0000 4 300 885 8625 1275 Target\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 7575 4725 0\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 7500 2475 2\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 7725 5100 0\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 10125 5100 1\001 +4 0 0 50 -1 0 12 0.0000 4 135 105 10425 2400 2\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 9000 3300 0\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 7800 2175 1\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 10050 2175 2\001 +4 0 1 50 -1 0 12 0.0000 4 135 105 8700 3600 1\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 3525 2025 3\001 +4 0 2 50 -1 0 12 0.0000 4 135 105 2325 2025 2\001 diff --git a/doc/doxygen/figures/OverlapDEC1.png b/doc/doxygen/figures/OverlapDEC1.png new file mode 100644 index 0000000000000000000000000000000000000000..d6fbd3f0b165688dad3e56a9a332e8a01d8e0b10 GIT binary patch literal 6982 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 T3*))D4K~{1{l)kHvBLiwHX_6V literal 0 HcmV?d00001 diff --git a/doc/doxygen/figures/UML_light.png b/doc/doxygen/figures/UML_light.png index 8eff5fa9c564a18200e14ddeff717d653cc8eff1..08ecacdbb7ccf09599668346827a52e6316f4a3e 100644 GIT binary patch literal 3990 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 literal 2803 zcmb_eX;4$=8a_!#iV$zDNE1)otMqDG@RUT{t^@_QM&q7wNrX8XHWiQ(1Bh&1M_Z1O zK{SkFT`DSDfT&am5UL&(0|pQwifmf6mB^A&z(8`plLV?W{c-Qi{gXL--}^q#^R6Gq z)~#JJ)(LikAZYBWmA)Gwh&&y9TO7&Y_i9UO76dt!tn&5QBztOjF53TW{x~S0)v{^f zhJEMb!td5@n=v0Eji($EnTiV2P9oL8!>`_qp|?46$I%|| zt6v55H@?91!y-UW=XCaGo*5{cWHq~lBmhDhN0P&y!lnSfO9;XDwvnk6(ZHX^?s(_* zy=I^>JYxKZ{KsQhs`sX$M;6CPJak=cvKl+KBB7mq6>dA_1cUF=xpAWHqguuhTXv{o(;!-rc^~ON& z&XB^Xr5s7WjD%HoM9sEbtZr&ngnB!`IwpV9>AbK47ZzOqzPlNMlkdLiGgsdXF!a&{ zTK!TqMjWLextui|&TJw#9>sSwGgT4Z_%O2{E#m8@2hoq5#*IkzXC~vploFswkx?fT z=}+K${$)_QgFHy2^>wm%ek<-EXS`3x75Y4nZ(SDGF$1q6Fe;f_S%{IIadEAG5{xG8 zX=EzS;|T_Ek-u>CoN_ai&R>UWq!{8U%*5x9y&0O4QR%>?eQI9I{M+*&x*eW?$;z14 z0W<~?{?FxrnC5mB@h=6UbN&I}CJ1c&6qm=$0uid!ZvG4l0M`?3{E1^i=uP>Eq%%7i zC$8x>Z;efhXJms9N?g-y-fh|Se+!bc)*j1b&JiNixjsawwCMbWcWRlSXFZpFC0{Ub z>d&YP0>|y3@LD=ZV}X)rBa3FJsX_gkO9PpNW@R=}O{>8*C29t!8PL9M1?>sZLYG*AXDN*A;>_1Gb9eC+fi(g{tO8CB-l`F zkd^Kb@PTY7HppZV1ehTkiXE~P0?hxDFn}WVK|f*aBKJ7Kl#ikO83{ri(<&a{Ga9gr zijkg2|Gy%>67!DhMWpK%%XrY7VXW|%aA;D}dE{H{*iaXtN2kE?F7trx^F4l2Fl`Om zAwagyYIA+kGv|BM$=mNZ?l5&Aw!Dmt5AGk8~AP!~Ujyb3T5s z{QKgU+QqpfaR5o#8E@!&Ym$7q2UH-py+Ml|TOvRi8u#$;bc*9x^x`Ri4aBZkj}1OZ z!8Pt}uAHoRwA?eT^Txw&!9S_3B!?cSRb_RGjbWf@zvY3tl|oVys1*@P220hub^=!D z404v;I;?om-3-<_nb_6<$SoGt4Yw+3g|fRjhxWY;qenbVYF48hNlSFaxyfB*aWD7-cQ0@Teo=5*SDaazDDr3Y{3ryo0zNhDKtPW& zc&O|y8_ZNGAzKNCsf$d+!UTHGBSZ%WrF`lJwuAcY%J#@ztraCE%g~z8lzUZA_VJDA?(MDPa{a<*r$owy#UcF75{|^kD?aiIBCVW>>En)om!Y$d zdl`v?U80wA&Aco4%%{{F@&ik|X{nyDsv$kQ_heX4Ozxh`qH$-#20J`<{v0957EjMZyn?l}TaZi|J>&n)6dUPt0n%SyK7&4$z7#+kn!5&^18ulA|&FXx!E z(;|um(dieFUaqSp8~@?l4nxm5)giGy=dH9dRTSQH`%cN?MdOFmMFVR#iG%rrIae|p zlCZ5U-TjFRG#5af!@mJ7@JZ!CZ-UZ;{#h^)Y$*{h23U=r5k2Kr>;CJ@cSofpB^d2n zwT3lKRC}9*|4Dtsw)frqw(6GH7n$RgM3bk5NjC0H{O#*wUmOt0?!!OWL6VGwH1Y!5H@)4^wj^> zMN3SV6WGc%Rnx&d5z}l}GjHY`tNPxEG8ZDgpUAOYmu}Gx(Pe z*zpp^$gb8{(`OS4@&we5?ooRN2*RzWGc2 Gll}vI@+C+B diff --git a/doc/doxygen/figures/UML_small.png b/doc/doxygen/figures/UML_small.png index 77109ab34035dcf9e9efddfdfc74e42de40087d0..791728fa43c41d13151b8666998e6a54a2168372 100644 GIT binary patch literal 27022 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 T@A`L$xMwjl+GbclbBXvLPlWqV literal 25901 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 A+5i9m diff --git a/doc/doxygen/grid.dox b/doc/doxygen/grid.dox index 36e09d3f8..07c6f5122 100644 --- a/doc/doxygen/grid.dox +++ b/doc/doxygen/grid.dox @@ -3,10 +3,10 @@ \section GRIDgeneral General Information The GRID class represents structured meshes in the MEDMEM library. -As the GRID class inherits from MESH, all of the functionalities that were -described in the previous section apply for structured mesh GRID objects. -In particular, reading and writing from files, general information access -are similar. However, because of the particular nature of structured meshes, +The GRID class inherits mesh common information from GMESH class, +in particular, reading and writing from files (c.f. \ref MESH_io), general information +access (c.f. \ref MESH_general), +access to families and other supports (c.f. \ref MESH_families). However, because of the particular nature of structured meshes, there exist methods to access information related to the axes of the grid. The numbering of the cells and nodes in a grid starts at one and @@ -17,5 +17,8 @@ of the last axis (c.f. figure \ref fig_grid_connectivity} ). \section grid_outline Outline -Constructors are defined in \ref GRID_constructors, methods related to axes are defined in \ref GRID_axes, while connectivity methods are given in \ref GRID_connectivity. +Constructors are defined in \ref GRID_constructors, methods related to +axes are defined in \ref GRID_axes, while connectivity methods are +given in \ref GRID_connectivity. A structured mesh can be obtained from +a GRID using MEDMEM::GRID::convertInMESH() method. */ diff --git a/doc/doxygen/medfilebrowser.dox b/doc/doxygen/medfilebrowser.dox new file mode 100644 index 000000000..622f00666 --- /dev/null +++ b/doc/doxygen/medfilebrowser.dox @@ -0,0 +1,22 @@ + +/*! +\page MEDFILEBROWSER_class MEDFILEBROWSER + +\section MED_general General Information + +This object is used to get information about the different +meshes/fields that are contained in a file. +This enables the user to know about the file content without +loading med objects in memory. + +\section MEDFILEBROWSER_object_outline Outline +The methods are described in the following sections : +- \ref MEDFILEBROWSER_constructors +- \ref MEDFILEBROWSER_query + +For an example using these methods, one may see the Python scripts in the +directory \c $MED_ROOT_DIR/bin/salome/,\c med_test1.py, or C++ +example program in the directory \c $MED_SRC_DIR/src/MEDMEMBinTest, +\c duplicateMED.cxx. + +*/ diff --git a/doc/doxygen/medmem.dox b/doc/doxygen/medmem.dox index 8cc256ec4..b928388df 100644 --- a/doc/doxygen/medmem.dox +++ b/doc/doxygen/medmem.dox @@ -13,10 +13,9 @@ The Med libraries are oganized in multiple layers: - CORBA API to simplify distributed computation inside SALOME (Server Side). - MED Client classes to simplify and optimize interaction of distant objects within the local solver. -Thanks to Med Memory, any component can access a distant -mesh or field object. Two codes running on -different machines can thus exchange meshes and fields. -These meshes and fields can easily be read/written in a Med file +Thanks to Med Memory, any component can access a distant mesh or field +object. Two codes running on different machines can thus exchange +meshes and fields. These meshes and fields can easily be read/written in a Med file format, enabling access to the whole Salome suite of tools (CAD, meshing, Visualization, other components). @@ -26,13 +25,14 @@ In this document, we describe the API of the Med Memory library (available in C+ As will be seen in section \ref medmem_api, the API consists of very few classes: -- a general MED container : \ref MED_class, +- a MED-file browser : \ref MEDFILEBROWSER_class, - meshes : \ref mesh , - structured meshes : \ref grid , - supports and derived classes : \ref support , - mesh generation tool : \ref meshing , - fields : \ref field , -- \ref medmem_drivers "drivers for reading and writing" in MED, GIBI and VTK files. +- \ref medmem_drivers "drivers for reading and writing" in MED, GIBI, +VTK, EnSight and Porflow files. All these are detailed in the following sections. The C++ formalism will be used for the description in these sections. @@ -85,7 +85,7 @@ a temperature at times \a t=0.0 s, \a t=1.0 s, \a t=2.0 s will be considered as MEDMEM supports data exchange in following formats: - \b GIBI - reading and writing the mesh and the fields in ASCII format. - \b VTK - writing the mesh and the fields in ASCII and binary formats. -- \b EnSight - reading and writing the mesh and the fields in ASCII and binary formats. +- \b EnSight - reading and writing the mesh and the fields in EnSigth6 and EnSigth GOLD formats (ASCII and binary). - \b PORFLOW - reading the mesh in ASCII format. Limitation of length of names in GIBI format is overcome by storing names in the specific string pile of GIBI file. @@ -124,7 +124,7 @@ At a basic usage level, the API consists in few classes which are located in the \c MEDMEM C++ namespace (consult figure \ref fig_UML_light which gives an UML diagram view of the main Med Memory classes): -- \b MED the global container; +- \b MEDFILEBROWSER the class provinding information on meshes and fields conatained in a MED file; - \b MESH the class containing 2D or 3D mesh objects; - \b SUPPORT the class containing mainly a list of mesh elements; - \b FIELD the class template containing list of values lying on a particular support. @@ -146,8 +146,7 @@ of the mesh; - read/write such fields. Note that on the figure \ref fig_UML_light as well as on figure -\ref fig_UML that the -MED container controls the life cycle of all the objects it contains: its destructor will destroy all the objects it aggregates. On the other hand, the life cycle of mesh, support and field objects are independent. Destroying a support (resp. a field) will have no effect on the mesh (resp. support) which refers to it. But the user has to maintain the link: a mesh aggregates a support which aggregates a field. If the user has to delete Med Memory objects, the field has to be deleted first, then the support and finally the mesh. +\ref fig_UML the life cycle of mesh and field objects are independent. Destroying a field will have no effect on the mesh. But the user has to maintain the link: a mesh aggregates a support which aggregates a field. If the user has to delete Med Memory objects, the field has to be deleted first, then the support and finally the mesh. A more advanced usage of the Med Memory is possible through other classes. Figure \ref fig_UML gives a complete view of the Med Memory API. It includes : @@ -196,25 +195,25 @@ only \b node and \b cell are considered. In 2D mesh, only \b node, available types are linear and quadratic elements (consult \ref RefManualMedMemory). The entries of this enum are quite self-explanatory : - - \c MED_NONE - - \c MED_POINT1 - - \c MED_SEG2 - - \c MED_SEG3 - - \c MED_TRIA3 - - \c MED_QUAD4 - - \c MED_TRIA6 - - \c MED_QUAD8 - - \c MED_TETRA4 - - \c MED_PYRA5 - - \c MED_PENTA6 - - \c MED_HEXA8 - - \c MED_TETRA10 - - \c MED_PYRA13 - - \c MED_PENTA15 - - \c MED_HEXA20 - - \c MED_POLYGON - - \c MED_POLYHEDRA - - \c MED_ALL_ELEMENTS + - \c MEDMEM_NONE + - \c MEDMEM_POINT1 + - \c MEDMEM_SEG2 + - \c MEDMEM_SEG3 + - \c MEDMEM_TRIA3 + - \c MEDMEM_QUAD4 + - \c MEDMEM_TRIA6 + - \c MEDMEM_QUAD8 + - \c MEDMEM_TETRA4 + - \c MEDMEM_PYRA5 + - \c MEDMEM_PENTA6 + - \c MEDMEM_HEXA8 + - \c MEDMEM_TETRA10 + - \c MEDMEM_PYRA13 + - \c MEDMEM_PENTA15 + - \c MEDMEM_HEXA20 + - \c MEDMEM_POLYGON + - \c MEDMEM_POLYHEDRA + - \c MEDMEM_ALL_ELEMENTS . The connectivity of all these elements is defined in MED project Web page http://hammi.extra.cea.fr/static/MED/web_med/logiciels/med-2.3.1/doc/ . @@ -237,6 +236,8 @@ The classes that make up the API of the library are : - \ref noncoincidentdec for a non-conservative interpolation based on element localization, - \ref structuredcoincidentdec for remapping coincident meshes on a one-to-one basis. This class applies to structured topologies. - \ref explicitcoincidentdec for remapping coincident meshes on a one-to-one basis. This class applies to unstructured topologies, + - \ref overlapdec based on intersecting elems volume + computation with source and target meshes are on same process id */ @@ -276,4 +277,3 @@ The following options can be useful to configure MEDMEM : - \a --with-lam=${LAMDIR} specifies an install path for a LAM MPI library, - \a --with-mpich=${MPICHDIR} specifies an install path for a MPICH-1 library. */ ->>>>>>> 1.1.4.1.2.1 diff --git a/doc/doxygen/mesh.dox b/doc/doxygen/mesh.dox index 9a82793da..52ff8f25c 100644 --- a/doc/doxygen/mesh.dox +++ b/doc/doxygen/mesh.dox @@ -3,21 +3,23 @@ \section mesh_general General information -The MESH class is dedicated to the handling of unstructured meshes. Two classes derive from it : MESHING supplies functions for creating meshes from scratch (c.f. \ref meshing), while GRID gives specific constructors for creating structured meshes. +The MESH class is dedicated to the handling of unstructured +meshes. Class MESHING deriving from it supplies functions for creating meshes from scratch (c.f. \ref meshing). \section mesh_connectivity Content of the connectivity array -Underlying the unstructured meshes is the notion of connectivity. This section only covers meshes made out of standard elements, the \c MED_POLYGON and \c MED_POLYHEDRA case being detailed in section \ref polygon . +Underlying the unstructured meshes is the notion of connectivity. This section only covers meshes made out of standard elements, the \c MEDMEM_POLYGON and \c MEDMEM_POLYHEDRA case being detailed in section \ref polygon . \anchor medmemConnArrays \image html connectivity_arrays_small.png "Nodal connectivity storage scheme" \image latex connectivity_arrays_small.eps "Nodal connectivity storage scheme" -In MEDMEM, an unstructured mesh nodal connectivity is defined with these arrays (if the mesh has no MED_POLYGON and MED_POLYHEDRA element) : -- the type array, which contains the number of cells for each present type -- the nodal connectivity array containing the connectivity of each cell, all cells being sorted by type, -- the connectivity index array, which indicates the beginning of each cell in the connectivity array, +In MEDMEM, an unstructured mesh nodal connectivity is defined with these arrays: +- the type array, which contains the number of cells for each present type; +- the nodal connectivity array containing the connectivity of each cell, all cells being sorted by type; +- the connectivity index array, which indicates the beginning of each cell in the connectivity array. -The cell types are ordered by their number of nodes. +The cell types are ordered by their number of nodes; MEDMEM_POLYGON and +MEDMEM_POLYHEDRA is always the last type, if present. As an example, let us consider a mesh made out of a linear triangle, two linear quadrangles and a quadratic triangle (c.f. figure \ref fig_connectivity_example ). \image html connectivity_example_small.png "Example for mesh connectivity" @@ -25,7 +27,7 @@ As an example, let us consider a mesh made out of a linear triangle, two linear The number of types is : 3 The type array writes : -\{ \a MED_TRIA3, \a MED_QUAD4, \a MED_TRIA6 \} +\{ \a MEDMEM_TRIA3, \a MEDMEM_QUAD4, \a MEDMEM_TRIA6 \} The global numbering index is : \{ 1,2,4,5 \} }. Its dimension is \f$ n_{types}+1 \f$ so that elements of type \f$ type[i] \f$ are stored between element \f$ index[i] \f$ and @@ -56,6 +58,7 @@ The description of MESH methods is given by the following sections : - Connectivity information methods are described in \ref MESH_connectivity. - The methods retrieving family information are given in \ref MESH_families. - The IO methods are given in \ref MESH_io. -- The methods for an advanced usage (applying algorithms to meshes) are given in \ref MESH_advanced. +- The methods for an advanced usage (applying algorithms to meshes) +are given in \ref MESH_advanced. */ diff --git a/doc/doxygen/meshing.dox b/doc/doxygen/meshing.dox index de2565a2c..20d87bfdd 100644 --- a/doc/doxygen/meshing.dox +++ b/doc/doxygen/meshing.dox @@ -12,14 +12,14 @@ dimensions are wrong, results are impredictable. All the arrays passed as arguments in the set methods are duplicated in MESHING object. The creation of a mesh should respect the following sequence : -- setting general information (name, description, dimensions, coordinate system, ...), +- setting general information (name, description, coordinate system, ...), - setting the nodes (number and coordinates), - setting the connectivity (types, connectivity arrays,...), - group creations. The following paragraphs describe the methods that must be called when creating a mesh. An example illustrates the general procedure. -The specific case of \c MED_POLYGON and \c MED_POLYHEDRA +The specific case of \c MEDMEM_POLYGON and \c MEDMEM_POLYHEDRA elements requires some methods that are described in \ref polygon. \section outline_meshing Outline @@ -37,4 +37,4 @@ An example of mesh creation via MESHING is given in : - Python: \include MESHINGexample.py -*/ \ No newline at end of file +*/ diff --git a/doc/doxygen/polygon.dox b/doc/doxygen/polygon.dox index 75054cd7a..ea5121a1c 100644 --- a/doc/doxygen/polygon.dox +++ b/doc/doxygen/polygon.dox @@ -4,12 +4,12 @@ The methods described in section \ref mesh do not take into account information about \c polygonal and \c polyhedral cells contained in a MESH object. -Indeed, in the MEDMEM library, the connectivity data -for these elements are stored separately . Therefore, -the methods that give access to this data are slightly different from -those of section \ref mesh. +Indeed, in the MEDMEM library, the connectivity data for these +elements are stored the same way as connectivity of standard +elements. Therefore, the methods that give access to this data are +same as those of section \ref mesh. -Also, the polygon and the polyhedra case differ in nature, +The polygon and the polyhedra case differ in nature, because in 3D, the list of nodes is not sufficient to described the shape of an element. A descending cell>face>nodes connectivity has to be established @@ -24,49 +24,35 @@ Let us consider the case illustrated in figure \ref fig_polygon_connectivity . \image latex polygon_connectivity_small.eps "Example for polygon connectivity" -- The standard element connectivity table writes : {2, 6, 7, 3, 3, 7, 8, 4 } -- The standard element connectivity index table writes : {1, 5, 9 } -- The polygon element connectivity table writes : {1, 2, 3, 4, 5 } -- The polygon element connectivity index table writes : {1, 6 } +- The connectivity table writes : {2, 6, 7, 3, 3, 7, 8, 4, 1, 2, 3, 4, 5 } +- The connectivity index table writes : {1, 5, 9, 14 } \section polyhedron_conn Polyhedron connectivity For polyhedra, in the nodal connectivity case, -one more array is required, because a -list of nodes does not suffice to describe a general polyhedron. -A general polyhedron is therefore described by a list of faces, -each of those being described by a list of nodes. +list of nodes does not suffice to describe a general polyhedron; +information of connectivity of each face is needed. +A general polyhedron is therefore described by a list of nodes of +all faces with -1 as separator between faces. Let us consider an example with the two tetrahedra represented on figure \ref fig_polyhedron_connectivity , the left one -being stored as a \c MED_TETRA4 element, the right one being stored -as a \c MED_POLYHEDRA element. +being stored as a \c MEDMEM_TETRA4 element, the right one being stored +as a \c MEDMEM_POLYHEDRA element. \anchor fig_polyhedron_connectivity \image html polyhedron_connectivity_small.png "Example for polyhedron connectivity. Node numbers are written with a normal font, while face numbers are written in italic font." \image latex polyhedron_connectivity_small.eps "Example for polyhedron connectivity. Node numbers are written with a normal font, while face numbers are written in italic font." -- The standard element index connectivity table writes : {1, 5 } -- The standard element connectivity table writes : {1, 2, 3, 4 } -- The polyhedra connectivity index table writes :{1, 5} -- The polyhedra connectivity face index table writes : {1, 4, 7, 10, 13} -- The polyhedra connectivity (face/node connectivity) table writes : {2, 3, 5, 2, 4, 5, 4, 5, 3, 2, 3, 4} +- The connectivity table writes : {1, 2, 3, 4, 2, 5, 3, -1, 2, 4, 5, -1, 4, 3, 5, -1, 2, 3, 4} +- The index connectivity table writes : {1, 5, 20 } -Note that as they are not needed as such, the face numberings are not stored -in any array. Only the number of nodes per face is implicitly stored -in the polyhedra face connectivity index table. - -If there are two \c MED_POLYHEDRA elements that share a common face, +If there are two \c MEDMEM_POLYHEDRA elements that share a common face, the list of nodes is repeated twice in the polyhedron connectivity -array. - -\section poly_outline Outline -The methods associated to polygons/polyhedra are located in the following classes : -- access methods are stored in MESH : \ref MESH_poly -- creation methods are in MESHING : \ref MESHING_poly +array but with reversed order. \section poly_example Example The following example illustrates the creation method for a mesh that contains polygons and/or polyhedra : \include test_MEDMEM_MeshingPoly.cxx -*/ \ No newline at end of file +*/ diff --git a/resources/Box1.med b/resources/Box1.med index 329a2860e8b933392308e63ff02cebd17ecd4c04..d1687755a1a5ddc13297783b9c6ec29f3303a752 100644 GIT binary patch delta 16 XcmZ2-k#WgI#tkYwjBJ}#dFo>THwXoj delta 16 XcmZ2-k#WgI#tkYwjEtLAdFo>THtGeA diff --git a/resources/Box1Moderate.med b/resources/Box1Moderate.med index 3fef76cd2e9ac2f6c7eb3183fcb35fa869b89dbe..28d53d56728fa4a7d0a2a2c8f624322c64b4e623 100644 GIT binary patch delta 24 fcmX?dgY(D@&J8L&jBL%SJngDHjN4UtnB)@xZR7_C delta 26 icmX?dgY(D@&J8L&lUbw$noW4xO?Vi$oA59RBme+|s0ZKx diff --git a/resources/Box2.med b/resources/Box2.med index adc472503ecb2bd91bda1fd69a603896c2748225..a7c9e049fa2217e2b65a2c61e537900ea41d20a4 100644 GIT binary patch delta 16 Ycmexzp7G0h#tkYwjBJ}#dCo@z06>8TegFUf delta 16 Ycmexzp7G0h#tkYwjEtLAdCo@z06=2~c>n+a diff --git a/resources/Box2Moderate.med b/resources/Box2Moderate.med index 9aaa9ffb30a24fdc4d6be922f97961211af6053e..c68570b46fab16c0371b7307dd75cade911ffa28 100644 GIT binary patch delta 24 fcmcaIh4ac3&J8L&jBL%SJngDHjN4UtnDp%cWkv>$ delta 26 icmcaIh4ac3&J8L&lUbw$noW4xO?Vi$oA59x*Z}}~ItOL| diff --git a/resources/Box3.med b/resources/Box3.med index 9686dfb485ec8a75bb95d854b0d3232c98834397..d9158ff61921943e73be734588ff4d345ebb9326 100644 GIT binary patch delta 16 XcmZp<#n^I-af1pEBim+Gp8E*^H6I1Z delta 16 XcmZp<#n^I-af1pEBjaXOp8E*^H30?0 diff --git a/resources/BoxEvenSmaller1.med b/resources/BoxEvenSmaller1.med index e789adaec5f574548b8633302ad4c144ba0092e5..79a495abc1a8cc8c9a76eb2e68cb9fc3b3700327 100644 GIT binary patch delta 16 YcmZ4TjB&{`#tkYwjBJ}#dH$yX06IwqM*si- delta 18 acmZ4TjB&{`#tkYwlUbw$Hkd<_Kv3 diff --git a/resources/DividedGenTetra1.med b/resources/DividedGenTetra1.med index 564cad0c9c98d4ce1e86b5dba4228bf1d1f493de..71274ea709a1151a37a2f411e948b48ffb3e4ead 100644 GIT binary patch delta 16 YcmdmUka^ER<_#)5jBJ}#d8S_h066LfHvj+t delta 18 acmdmUka^ER<_#)5laKHSY&PNPxB>u7o(H1< diff --git a/resources/DividedGenTetra2.med b/resources/DividedGenTetra2.med index fcfee02c8271f1c8b52cd80e71a9482d5ddc9b78..14f63cd5ffa3a57c18a832faa068faee65fc6239 100644 GIT binary patch delta 16 YcmexzmGR3}#tkYwjBJ}#dCtcH06``OjQ{`u delta 18 acmexzmGR3}#tkYwlaKHSY&PLJ5C;HO0tfj3 diff --git a/resources/DividedUnitTetra.med b/resources/DividedUnitTetra.med index f2feced90c04deb5c1b9bf1b0f659de4dbc7a3e6..320bdfa3d8cfdce11628d27454c424a7280055e7 100644 GIT binary patch delta 16 XcmdmTk#WmK#tkYwjBJ}#dHQ1jIQRv_ delta 18 acmdmTk#WmK#tkYwlaKHSY&PL(hyegh#0M_` diff --git a/resources/DividedUnitTetraSimpler.med b/resources/DividedUnitTetraSimpler.med index 5dfbeb1f57c4c1e88a67e142e04cf49a28f9d8c3..a826cfbebcacba717c745ca5f508b8af4b954f2f 100644 GIT binary patch delta 16 YcmX?en(@qO#tkYwjBJ}#d6q{406RMc`~Uy| delta 18 acmX?en(@qO#tkYwlaKHSY&PMU5eWcKPX}lK diff --git a/resources/GenTetra1.med b/resources/GenTetra1.med index 4683d902d77f452cc96dfec61776403a29095344..629b29928374e94feb57b1e4c8f3a580b2e70e9e 100644 GIT binary patch delta 18 acmaEJlJU(+#tkYwlN;2yHtX^1ivR#o)(4XS delta 22 ecmaEJlJU(+#tkYwlQ%?iP3Dtg+ib$KBLV<(2ne?T diff --git a/resources/GenTetra2.med b/resources/GenTetra2.med index 6b88cd2a2eadf58ba2dbe9dc431e11ee7214fd51..32e3bb51e35130b526754f28848d213c9b118e95 100644 GIT binary patch delta 18 acmaEJlJU(+#tkYwlN;2yHtX^1ivR#o)(4XS delta 22 ecmaEJlJU(+#tkYwlQ%?iP3Dtg+ib$KBLV<(2ne?T diff --git a/resources/GeneralTetra.med b/resources/GeneralTetra.med index 38d0747a3b29e7de2b353d96f5d36ad334e92cd4..11b2e27855f4112eaefa2b8d18820f3921bc2bc0 100644 GIT binary patch delta 16 XcmZ2;l5x#R#tkYwjBJ}#dD(4rVT1QjBJ}#dH6R206ixK_5c6? delta 17 Zcmdn;k7>(4rVT1QlUbw$7Mt*F1^`9S2A}`{ diff --git a/resources/NudgedDividedUnitTetra.med b/resources/NudgedDividedUnitTetra.med index c19006836243bc978cea571bc39ccbe1ef637be8..67aabde0b4e7b84bcae89903b73d1ba90a54dd83 100644 GIT binary patch delta 16 XcmdmTk#WmK#tkYwjBJ}#dHQ1jIQRv_ delta 18 acmdmTk#WmK#tkYwlaKHSY&PL(hyegh#0M_` diff --git a/resources/NudgedDividedUnitTetraSimpler.med b/resources/NudgedDividedUnitTetraSimpler.med index d71c6e6801ff2ad5d67060e8f7989d55d6a47e27..2eb145e5e17412eefd56c7c899d88c52794980d4 100644 GIT binary patch delta 16 YcmX?en(@qO#tkYwjBJ}#d6q{406RMc`~Uy| delta 18 acmX?en(@qO#tkYwlUbw$Hkd<_Kv3 diff --git a/resources/SimpleIncludedTetra.med b/resources/SimpleIncludedTetra.med index 127d890d4d9313c339b083e44fdf498818bd8fde..9ac90ee1bac67987e31ae2b227b06e1372b5f335 100644 GIT binary patch delta 16 XcmZ2;l5x#R#tkYwjBJ}#dDd<_Kv3 diff --git a/resources/SimpleIncludingTetra.med b/resources/SimpleIncludingTetra.med index e72ef08797072329ac1dff807b3768127e0d6d15..e0d6066d09a59217e42ea322a6bb789a74729005 100644 GIT binary patch delta 16 XcmZ2;l5x#R#tkYwjBJ}#dDd<_Kv3 diff --git a/resources/TinyBox.med b/resources/TinyBox.med index 3f76ecd8052edf7c8c35dd07a90b9582e38acc4c..2ae80ef4f183d42efb4821ba6a6da29c8418de79 100644 GIT binary patch delta 16 Ycmexzp7G0h#tkYwjBJ}#dCo@z06>8TegFUf delta 16 Ycmexzp7G0h#tkYwjEtLAdCo@z06=2~c>n+a diff --git a/resources/TrickyTetra1.med b/resources/TrickyTetra1.med index 32b45916aed7580c77c2e59940deb5549d92c32a..50c0aa98acee35814b172e23642398778465baf3 100644 GIT binary patch delta 16 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 B-+KT6 delta 5868 zcmdT|eNa@_6@T~bLf(ELPhi;v6&9heQNiVFg01afW7CaA!Guh)A_#ZW$U9{f2AA%KKa zPrZP4p^#`;!aEI|ljFFGAo)WEF_uR6VI~h8h9AT&fzG%b_>s8>!u4Xv7e9```z?WQ znQZM(r7jKL1nyMT3urF_=Sl%`a>dXxvqv(5!DC|UIe}V*x-CCNc%Ki&!*H>PUE7fe z)vHoA4i>Yml&xJwOy^`N616==ZzCi#J(|R%K!iI%Z*$PXbe{#DHJ^z?oS8$=+V>4y z?m|hp(uY!EVqOn_U|wr~26*F)FqAk2KOUF|wYe?`_PW6}-(%po8nXHs2>wcp&6g#` z=0nk>4>U2ou?UIyF&lD(E~lK-%=_|5tSjvT)UL9IMp6q*BnOqbrBLRK0TH0dsk#-j zmY^7x=EWMT;NqB743y5GJ6km$&H)FB@SBOm%;`3(KBgaz`A~4pVP##aT1At@(BM*Sno75k zG%<88h~{ge77NsMVwN>DSdbCR&m7x$+^V@;xjC$A3S(BU7Fkgc5{j~LWdceyTq)(C zzx)mGn=gTAaD+ySllWwTqb%z!)vyfeZzm%ME?j}KksCing$M7Z!i!C1L^R`kD*Sjo z6#@J_5qR@%B!--ibZs#-A5qQ?*~P4$Ib3cd>n4 zMs{Fs;p>ke`@V7l>(H168-0v2z4tFnx`;RsX3xrL8-JJSgR*oGb@(m4jk}BKf+C4p zene+u=Gud7Vh?2XB$LeT2f{w^<`^Mx-N+w^!|UxNCfY4JJC!(S)ZwFSUE5JycNHy2 z>(Ke-)YqZ0H9Vpn$T)nAgwHU&?F?8vvQi5sah&8M}1XP!(oSrokZ;-e@J*7kfKBE8Imw^#MhO*WG} z9C}CVf!1~+;Z7IReUb~*0_aj^Xkv{O@ti18?bYT*{D7ufW~a!OI}kfwGBsf+Tw)k{ zU$G>Vgo+yi-x~&!*Uj|fGyVsCKB|7tbeAmYktz9DZ_^fGdb2EP>)11(w~2ecImFJDVme=@@yB(T7#30Nfu&q$*8(z;diRl*#I$6#uBn zfLRSO){2ZJXJu@jbF;AxCF`(7hZz<&$#JX6N;(#v)nf~P;)c$T7zfHex&t5hBPE8K z5iKq?ttzfPB=r(w0)L*3%aN+X^X{|UoHzEsGCtL!KPo<@m~ z;V`vE9>V*INVA_QMBj$MdBKuW!F-Q@kHh`DQ7ZnO4duO7g#?TD3HGM!3F%Ggf|;3_ z+jMF^CranAx|$g*tDe2Ia|3(h-=KLDid?9OH-tY`@oK%N;lh+``LNr7;WFY@yeZas<_J1k#kK>$Lq^c znkg2l$|w&>hs3DbiP?;bEKo4wf|tqH>hBDblDHZam$Z6u58HOFNy-n^#^aw!Yf(wk(UhoA4p|8XXV`Ri>Wl5i9EBUa@?jJ+nNiV zPA3OHIh~BFUqWJn_Vrr)?2E{bAGY#|4q}y0O=pdKTzQRL-6FS*7WLx6&_F&C=>B$? zIBmx3PLqd@zBGLN6_lq;r_uZ^X1{c-oClwM38kSd{EU?^HcBTFM7WV@T45eTm{hF z#&iJFrL(D`Bs7V~-PZ^kWD4CMu6z|#^-}m?5}I}s+;R$8Gdc$Xbcz2w~^AtY`~9qqn$xO<63y%;{gvHVAJYku}?$$iI{ z?;hHCqV~&2n0_w|kKNk<9sR#%xO%yJfLU>ur&YZiKEScm+0pz^^WG*j*B|mPrW5}L D{blX< diff --git a/resources/polygones.med b/resources/polygones.med index a1c404d0adb0929aa4698fa33b3ce2f7046811c7..0782b0098984b8fc71c2107f426724e9d0c975a8 100644 GIT binary patch delta 35 rcmZ3}&$_0cwP6dRiTdP*xm=UoQuwC(s52@|=h0&1*j}Q}XrTZA;7$s{ delta 32 ocmZ3}&$_0cwP6dRiTd #include +#include #include #include #include @@ -73,6 +74,15 @@ void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception) val->setDouble(_value); } +void LeafExprVal::replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception) +{ + int pos=(int)_value; + int lgth=valuesInExpr.size(); + if(pos>=lgth || pos<0) + throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !"); + _value=valuesInExpr[pos]; +} + LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var) { } @@ -118,6 +128,13 @@ bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos) return true; } +/*! + * Nothing to do it is not a bug. + */ +void LeafExprVar::replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception) +{ +} + LeafExprVar::~LeafExprVar() { } @@ -140,19 +157,22 @@ ExprParser::~ExprParser() releaseFunctions(); } -std::size_t ExprParser::findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket) +std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket) { int level=0; - for(std::size_t iter=posOfCloseBracket-1;iter>=0;iter--) - if(expr[iter]==')') - level++; - else if(expr[iter]=='(') - { - if(level==0) - return iter; - else - level--; - } + for(std::size_t iter=0;iter valuesInExpr; + fillValuesInExpr(valuesInExpr); checkBracketsParity(); if(!simplify()) parseDeeper(); + replaceValues(valuesInExpr); + _expr=tmp; } _is_parsing_ok=true; } @@ -378,7 +403,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception) return ; //at this level of code _expr std::size_t pos1=_expr.find_first_of('('); - std::size_t pos4=findCorrespondingOpenBracket(_expr,_expr.length()-1); + std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1); if(pos4!=pos1) return ; std::string funcName=_expr.substr(0,pos1); @@ -423,7 +448,7 @@ bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception) { std::size_t pos=_expr.find_first_not_of("+-",0,2); std::string minimizedExpr=_expr.substr(pos); - std::size_t pos2=minimizedExpr.find_first_of("+-*/^()",0,7); + std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9); if(pos2!=std::string::npos) return false; delete _leaf; @@ -464,7 +489,7 @@ void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception) char MSGTYP1[]="Error non unary function for '"; errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; std::string tmp=_expr.substr(iter-_expr.begin()); - locateError(errMsg,tmp,0); + LocateError(errMsg,tmp,0); throw INTERP_KERNEL::Exception(errMsg.str().c_str()); } break; @@ -589,7 +614,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception) char MSGTYP1[]="Error non unary function for '"; errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; std::string tmp=_expr.substr(iter-_expr.begin()); - locateError(errMsg,tmp,0); + LocateError(errMsg,tmp,0); throw INTERP_KERNEL::Exception(errMsg.str().c_str()); } } @@ -650,7 +675,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception) char MSGTYP1[]="Error non unary function for '"; errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; std::string tmp=_expr.substr(iter-_expr.begin()); - locateError(errMsg,tmp,0);curPart+=*iter; + LocateError(errMsg,tmp,0);curPart+=*iter; throw INTERP_KERNEL::Exception(errMsg.str().c_str()); } break; @@ -719,7 +744,7 @@ bool ExprParser::simplify() throw(INTERP_KERNEL::Exception) std::ostringstream errMsg; char MSGTYP3[]="Error in interpreting : "; errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr; - locateError(errMsg,_expr,0); + LocateError(errMsg,_expr,0); throw INTERP_KERNEL::Exception(errMsg.str().c_str()); } return false; @@ -740,7 +765,7 @@ void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception) std::ostringstream errMsg; char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('"; errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1; - locateError(errMsg,_expr,iter-_expr.begin()); + LocateError(errMsg,_expr,iter-_expr.begin()); throw INTERP_KERNEL::Exception(errMsg.str().c_str()); } curLevel--; @@ -755,7 +780,140 @@ void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception) } } -void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr) +/*! + * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end). + * If double representation is invalid an exception is thrown. + * This method returns a delta that is the delta to operate to pos in expr after substitution. + */ +double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception) +{ + static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !"; + std::istringstream stream; + std::ostringstream oss; + std::size_t end2=end!=std::string::npos?end-bg:end; + std::string tmp=expr.substr(bg,end2); + stream.str(tmp); + double ret=std::numeric_limits::max(); + stream >> ret; + if(stream.fail()) + throw INTERP_KERNEL::Exception(MSG); + if(!stream.eof()) + throw INTERP_KERNEL::Exception(MSG); + oss << id; + std::string tmp2(oss.str()); + std::size_t l1=tmp.length(); + delta=(int)tmp2.length()-(int)l1; + expr.replace(bg,l1,tmp2); + return ret; +} + +/*! + * This method makes the assumption that _expr has no white space. + * This method scans _expr finding in greedy mode the following pattern : + * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}? + */ +void ExprParser::fillValuesInExpr(std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception) +{ + const char FIGURES[]="0123456789"; + const std::string other("+-*^/(<>,"); + double val=std::numeric_limits::max(); + std::size_t lgth=_expr.length(); + int id=0,delta; + for(std::size_t pos=0;pos!=std::string::npos;id++) + { + std::size_t pos2=_expr.find_first_of(FIGURES,pos,10); + if(pos2>0) + {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this + if(other.find_first_of(_expr[pos2-1])==std::string::npos) + { + pos=_expr.find_first_not_of(FIGURES,pos2,10); + id--; + continue; + } + if(_expr[pos2-1]==')') + { + pos=_expr.find_first_not_of(FIGURES,pos2,10); + std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos); + oss << "\" is right after close parenthesis... ')'"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(pos2==std::string::npos) + break; + std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10); + if(pos3==std::string::npos) + {//"x+1223442320" + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); + break; + } + if(_expr[pos3]=='.') + pos3++; + if(pos3=lgth) + {//"x+1223334.223e+" or "1223334.223E-" + std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\""; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10); + if(pos4==pos5) + {//"x+1223334.223e+x" or "1223334.223E-y" + std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\""; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + //OK, normal case + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta)); + pos=pos5+delta; + continue; + } + else//"x+1223334.223e" + { + std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } + else + {//"x+1223334." + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); + break; + } + } +} + +void ExprParser::replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception) +{ + if(_leaf) + _leaf->replaceValues(valuesInExpr); + else + { + for(std::list::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).replaceValues(valuesInExpr); + } +} + +void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr) { stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; } diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx index 07334076e..c41455403 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -41,6 +41,7 @@ namespace INTERP_KERNEL virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0; virtual void compileX86(std::vector& ass) const = 0; virtual void compileX86_64(std::vector& ass) const = 0; + virtual void replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception) = 0; static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception); }; @@ -52,6 +53,7 @@ namespace INTERP_KERNEL void compileX86(std::vector& ass) const; void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); + void replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception); private: double _value; }; @@ -67,6 +69,7 @@ namespace INTERP_KERNEL std::string getVar() const { return _var_name; } void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception); + void replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception); static bool isRecognizedKeyVar(const std::string& var, int& pos); public: static const char END_OF_RECOGNIZED_VAR[]; @@ -113,8 +116,11 @@ namespace INTERP_KERNEL bool simplify() throw(INTERP_KERNEL::Exception); void releaseFunctions(); void checkBracketsParity() const throw(INTERP_KERNEL::Exception); - static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); - static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); + void fillValuesInExpr(std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception); + void replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception); + static double ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception); + static std::size_t FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); + static void LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); private: ExprParser *_father; bool _is_parsed; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx index ad23a0891..7e4ea2dc6 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx @@ -54,6 +54,10 @@ const char ExpFunction::REPR[]="exp"; const char LnFunction::REPR[]="ln"; +const char LogFunction::REPR[]="log"; + +const char Log10Function::REPR[]="log10"; + const char MaxFunction::REPR[]="max"; const char MinFunction::REPR[]="min"; @@ -102,6 +106,10 @@ Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) throw(INT return new ExpFunction; if(tmp==LnFunction::REPR) return new LnFunction; + if(tmp==LogFunction::REPR) + return new LogFunction; + if(tmp==Log10Function::REPR) + return new Log10Function; // std::string msg("Invalid unary function detected : \""); msg+=type; msg+="\""; @@ -399,6 +407,56 @@ bool LnFunction::isACall() const return true; } +LogFunction::~LogFunction() +{ +} + +void LogFunction::operate(std::vector& stack) const throw(INTERP_KERNEL::Exception) +{ + Value *val=stack.back(); + val->ln(); +} + +void LogFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); +} + +const char *LogFunction::getRepr() const +{ + return REPR; +} + +bool LogFunction::isACall() const +{ + return true; +} + +Log10Function::~Log10Function() +{ +} + +void Log10Function::operate(std::vector& stack) const throw(INTERP_KERNEL::Exception) +{ + Value *val=stack.back(); + val->log10(); +} + +void Log10Function::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); +} + +const char *Log10Function::getRepr() const +{ + return REPR; +} + +bool Log10Function::isACall() const +{ + return true; +} + int BinaryFunction::getNbInputParams() const { return 2; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx index 5ef74540f..e5619547f 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx @@ -178,6 +178,30 @@ namespace INTERP_KERNEL static const char REPR[]; }; + class INTERPKERNELEXPREVAL_EXPORT LogFunction : public UnaryFunction + { + public: + ~LogFunction(); + void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); + const char *getRepr() const; + bool isACall() const; + public: + static const char REPR[]; + }; + + class INTERPKERNELEXPREVAL_EXPORT Log10Function : public UnaryFunction + { + public: + ~Log10Function(); + void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); + const char *getRepr() const; + bool isACall() const; + public: + static const char REPR[]; + }; + class INTERPKERNELEXPREVAL_EXPORT BinaryFunction : public Function { public: diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx index 338541960..998f4ab31 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx @@ -90,11 +90,16 @@ void ValueDouble::exp() throw(INTERP_KERNEL::Exception) _data=std::exp(_data); } -void ValueDouble:: ln() throw(INTERP_KERNEL::Exception) +void ValueDouble::ln() throw(INTERP_KERNEL::Exception) { _data=std::log(_data); } +void ValueDouble::log10() throw(INTERP_KERNEL::Exception) +{ + _data=std::log10(_data); +} + Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception) { const ValueDouble *valC=checkSameType(other); @@ -238,6 +243,11 @@ void ValueUnit::ln() throw(INTERP_KERNEL::Exception) unsupportedOp(LnFunction::REPR); } +void ValueUnit::log10() throw(INTERP_KERNEL::Exception) +{ + unsupportedOp(Log10Function::REPR); +} + Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception) { unsupportedOp(PlusFunction::REPR); @@ -398,10 +408,18 @@ void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception) { double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !"); + throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !"); std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log)); } +void ValueDoubleExpr::log10() throw(INTERP_KERNEL::Exception) +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log10)); +} + Value *ValueDoubleExpr::plus(const Value *other) const throw(INTERP_KERNEL::Exception) { const ValueDoubleExpr *otherC=static_cast(other); diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx index 71f1b79fe..e581fbd5a 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx @@ -43,6 +43,7 @@ namespace INTERP_KERNEL virtual void abs() throw(INTERP_KERNEL::Exception) = 0; virtual void exp() throw(INTERP_KERNEL::Exception) = 0; virtual void ln() throw(INTERP_KERNEL::Exception) = 0; + virtual void log10() throw(INTERP_KERNEL::Exception) = 0; //binary virtual Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0; virtual Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0; @@ -75,6 +76,7 @@ namespace INTERP_KERNEL void abs() throw(INTERP_KERNEL::Exception); void exp() throw(INTERP_KERNEL::Exception); void ln() throw(INTERP_KERNEL::Exception); + void log10() throw(INTERP_KERNEL::Exception); // Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception); Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception); @@ -112,6 +114,7 @@ namespace INTERP_KERNEL void abs() throw(INTERP_KERNEL::Exception); void exp() throw(INTERP_KERNEL::Exception); void ln() throw(INTERP_KERNEL::Exception); + void log10() throw(INTERP_KERNEL::Exception); // Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception); Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception); @@ -151,6 +154,7 @@ namespace INTERP_KERNEL void abs() throw(INTERP_KERNEL::Exception); void exp() throw(INTERP_KERNEL::Exception); void ln() throw(INTERP_KERNEL::Exception); + void log10() throw(INTERP_KERNEL::Exception); // Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception); Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception); diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx index 157386825..ec30ddf04 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx @@ -32,7 +32,6 @@ namespace INTERP_KERNEL bool isIn(double characterVal) const { return true; } void dynCastFunction(const EdgeLin * &seg, const EdgeArcCircle * &arcSeg) const { seg=this; } - void dumpInXfigFile(std::ostream& stream) const { } private: ~EdgeInfLin() { } }; diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx index e96f3fc1b..0bdbd5480 100644 --- a/src/INTERP_KERNEL/InterpolationUtils.hxx +++ b/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -73,11 +73,11 @@ namespace INTERP_KERNEL } /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction qui calcul le déterminant */ + /* fonction qui calcul le determinant */ /* de deux vecteur(cf doc CGAL). */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - //fonction qui calcul le déterminant des vecteurs: P3P1 et P3P2 + //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2 //(cf doc CGAL). inline double mon_determinant(const double* P_1, @@ -181,8 +181,8 @@ namespace INTERP_KERNEL } /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul les coordonnées du barycentre d'un polygone */ - /* le vecteur en entrée est constitué des coordonnées */ + /* calcul les coordonnees du barycentre d'un polygone */ + /* le vecteur en entree est constitue des coordonnees */ /* des sommets du polygone */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ @@ -206,6 +206,57 @@ namespace INTERP_KERNEL return Bary; } + + /*! + * Given 6 coeffs of a Tria6 returns the corresponding value of a given pos + */ + inline double computeTria6RefBase(const double *coeffs, const double *pos) + { + return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[0]*pos[0]+coeffs[4]*pos[0]*pos[1]+coeffs[5]*pos[1]*pos[1]; + } + + /*! + * Given xsi,eta in refCoo (length==2) return 6 coeffs in weightedPos. + */ + inline void computeWeightedCoeffsInTria6FromRefBase(const double *refCoo, double *weightedPos) + { + weightedPos[0]=(1.-refCoo[0]-refCoo[1])*(1.-2*refCoo[0]-2.*refCoo[1]); + weightedPos[1]=refCoo[0]*(2.*refCoo[0]-1.); + weightedPos[2]=refCoo[1]*(2.*refCoo[1]-1.); + weightedPos[3]=4.*refCoo[0]*(1.-refCoo[0]-refCoo[1]); + weightedPos[4]=4.*refCoo[0]*refCoo[1]; + weightedPos[5]=4.*refCoo[1]*(1.-refCoo[0]-refCoo[1]); + } + + /*! + * Given 10 coeffs of a Tetra10 returns the corresponding value of a given pos + */ + inline double computeTetra10RefBase(const double *coeffs, const double *pos) + { + return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[2]+ + coeffs[4]*pos[0]*pos[0]+coeffs[5]*pos[0]*pos[1]+coeffs[6]*pos[0]*pos[2]+ + coeffs[7]*pos[1]*pos[1]+coeffs[8]*pos[1]*pos[2]+coeffs[9]*pos[2]*pos[2]; + } + + /*! + * Given xsi,eta,z in refCoo (length==3) return 10 coeffs in weightedPos. + */ + inline void computeWeightedCoeffsInTetra10FromRefBase(const double *refCoo, double *weightedPos) + { + //http://www.cadfamily.com/download/CAE/ABAQUS/The%20Finite%20Element%20Method%20-%20A%20practical%20course%20abaqus.pdf page 217 + //L1=1-refCoo[0]-refCoo[1]-refCoo[2] + //L2=refCoo[0] L3=refCoo[1] L4=refCoo[2] + weightedPos[0]=(-2.*(refCoo[0]+refCoo[1]+refCoo[2])+1)*(1-refCoo[0]-refCoo[1]-refCoo[2]);//(2*L1-1)*L1 + weightedPos[1]=(2.*refCoo[0]-1.)*refCoo[0];//(2*L2-1)*L2 + weightedPos[2]=(2.*refCoo[1]-1.)*refCoo[1];//(2*L3-1)*L3 + weightedPos[3]=(2.*refCoo[2]-1.)*refCoo[2];//(2*L4-1)*L4 + weightedPos[4]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[0];//4*L1*L2 + weightedPos[5]=4.*refCoo[0]*refCoo[1];//4*L2*L3 + weightedPos[6]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[1];//4*L1*L3 + weightedPos[7]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[2];//4*L1*L4 + weightedPos[8]=4.*refCoo[0]*refCoo[2];//4*L2*L4 + weightedPos[9]=4.*refCoo[1]*refCoo[2];//4*L3*L4 + } /*! * \brief Solve system equation in matrix form using Gaussian elimination algorithm @@ -221,37 +272,42 @@ namespace INTERP_KERNEL // make upper triangular matrix (forward elimination) int iR[nbRow];// = { 0, 1, 2 }; - for ( int i = 0; i < (int) nbRow; ++i ) iR[i] = i; - + for ( int i = 0; i < (int) nbRow; ++i ) + iR[i] = i; for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows { // swap rows to have max value of i-th column in i-th row double max = std::fabs( M[ iR[i] ][i] ); - for ( int r = i+1; r < (int)nbRow; ++r ) { - double m = std::fabs( M[ iR[r] ][i] ); - if ( m > max ) { - max = m; - std::swap( iR[r], iR[i] ); + for ( int r = i+1; r < (int)nbRow; ++r ) + { + double m = std::fabs( M[ iR[r] ][i] ); + if ( m > max ) + { + max = m; + std::swap( iR[r], iR[i] ); + } + } + if ( max < std::numeric_limits::min() ) + { + //sol[0]=1; sol[1]=sol[2]=sol[3]=0; + return false; // no solution } - } - if ( max < std::numeric_limits::min() ) { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } // make 0 below M[i][i] (actually we do not modify i-th column) double* tUpRow = M[ iR[i] ]; - for ( int r = i+1; r < (int)nbRow; ++r ) { - double* mRow = M[ iR[r] ]; - double coef = mRow[ i ] / tUpRow[ i ]; - for ( int c = i+1; c < nbCol; ++c ) - mRow[ c ] -= tUpRow[ c ] * coef; - } + for ( int r = i+1; r < (int)nbRow; ++r ) + { + double* mRow = M[ iR[r] ]; + double coef = mRow[ i ] / tUpRow[ i ]; + for ( int c = i+1; c < nbCol; ++c ) + mRow[ c ] -= tUpRow[ c ] * coef; + } } double* mRow = M[ iR[nbRow-1] ]; - if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits::min() ) { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } + if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits::min() ) + { + //sol[0]=1; sol[1]=sol[2]=sol[3]=0; + return false; // no solution + } mRow[ nbRow ] /= mRow[ nbRow-1 ]; // calculate solution (back substitution) @@ -270,6 +326,60 @@ namespace INTERP_KERNEL return true; } + + /*! + * \brief Solve system equation in matrix form using Gaussian elimination algorithm + * \param M - N x N+NB_OF_VARS matrix + * \param sol - vector of N solutions + * \retval bool - true if succeeded + */ + template + bool solveSystemOfEquations2(const double *matrix, double *solutions, double eps) + { + int nr,n,nx,k,np; + double s,g; + int m,mb,j; + // + double B[SZ*(SZ+NB_OF_RES)]; + std::copy(matrix,matrix+SZ*(SZ+NB_OF_RES),B); + // + nr=SZ+NB_OF_RES; + nx=nr*SZ; + for(k=0;keps) + {/* Rows permutation */ + for(m=0;m(),s)); + for(j=0;j& n, const double* p, double* bc) + /*! + * Calculate barycentric coordinates of a point p with respect to triangle or tetra verices. + * This method makes 2 assumptions : + * - this is a simplex + * - spacedim == meshdim. For TRI3 and TRI6 spaceDim is expected to be equal to 2 and for TETRA4 spaceDim is expected to be equal to 3. + * If not the case (3D surf for example) a previous projection should be done before. + */ + inline void barycentric_coords(const std::vector& n, const double *p, double *bc) { enum { _X, _Y, _Z }; - if ( n.size() == 3 ) // TRIA3 + switch(n.size()) { - // matrix 2x2 - double - T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], - T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; - // matrix determinant - double Tdet = T11*T22 - T12*T21; - if ( std::fabs( Tdet ) < std::numeric_limits::min() ) { - bc[0]=1; bc[1]=bc[2]=0; // no solution - return; + case 3: + { // TRIA3 + // matrix 2x2 + double + T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], + T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; + // matrix determinant + double Tdet = T11*T22 - T12*T21; + if ( std::fabs( Tdet ) < std::numeric_limits::min() ) + { + bc[0]=1; bc[1]=bc[2]=0; // no solution + return; + } + // matrix inverse + double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; + // vector + double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; + // barycentric coordinates: mutiply matrix by vector + bc[0] = (t11 * r11 + t12 * r12)/Tdet; + bc[1] = (t21 * r11 + t22 * r12)/Tdet; + bc[2] = 1. - bc[0] - bc[1]; + break; } - // matrix inverse - double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; - // vector - double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; - // barycentric coordinates: mutiply matrix by vector - bc[0] = (t11 * r11 + t12 * r12)/Tdet; - bc[1] = (t21 * r11 + t22 * r12)/Tdet; - bc[2] = 1. - bc[0] - bc[1]; - } - else // TETRA4 - { - // Find bc by solving system of 3 equations using Gaussian elimination algorithm - // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 - // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 - // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 - - double T[3][4]= - {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, - { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, - { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; - - if ( !solveSystemOfEquations<3>( T, bc )) - bc[0]=1., bc[1] = bc[2] = bc[3] = 0; - else - bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; + case 4: + { // TETRA4 + // Find bc by solving system of 3 equations using Gaussian elimination algorithm + // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 + // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 + // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 + + double T[3][4]= + {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, + { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, + { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; + + if ( !solveSystemOfEquations<3>( T, bc ) ) + bc[0]=1., bc[1] = bc[2] = bc[3] = 0; + else + bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; + break; + } + case 6: + { + // TRIA6 + double matrix2[48]={1., 0., 0., 0., 0., 0., 0., 0., + 1., 0., 0., 0., 0., 0., 1., 0., + 1., 0., 0., 0., 0., 0., 0., 1., + 1., 0., 0., 0., 0., 0., 0.5, 0., + 1., 0., 0., 0., 0., 0., 0.5, 0.5, + 1., 0., 0., 0., 0., 0., 0.,0.5}; + for(int i=0;i<6;i++) + { + matrix2[8*i+1]=n[i][0]; + matrix2[8*i+2]=n[i][1]; + matrix2[8*i+3]=n[i][0]*n[i][0]; + matrix2[8*i+4]=n[i][0]*n[i][1]; + matrix2[8*i+5]=n[i][1]*n[i][1]; + } + double res[12]; + solveSystemOfEquations2<6,2>(matrix2,res,std::numeric_limits::min()); + double refCoo[2]; + refCoo[0]=computeTria6RefBase(res,p); + refCoo[1]=computeTria6RefBase(res+6,p); + computeWeightedCoeffsInTria6FromRefBase(refCoo,bc); + break; + } + case 10: + {//TETRA10 + double matrix2[130]={1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5, 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0.5, 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.5, + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5}; + for(int i=0;i<10;i++) + { + matrix2[13*i+1]=n[i][0]; + matrix2[13*i+2]=n[i][1]; + matrix2[13*i+3]=n[i][2]; + matrix2[13*i+4]=n[i][0]*n[i][0]; + matrix2[13*i+5]=n[i][0]*n[i][1]; + matrix2[13*i+6]=n[i][0]*n[i][2]; + matrix2[13*i+7]=n[i][1]*n[i][1]; + matrix2[13*i+8]=n[i][1]*n[i][2]; + matrix2[13*i+9]=n[i][2]*n[i][2]; + } + double res[30]; + solveSystemOfEquations2<10,3>(matrix2,res,std::numeric_limits::min()); + double refCoo[3]; + refCoo[0]=computeTetra10RefBase(res,p); + refCoo[1]=computeTetra10RefBase(res+10,p); + refCoo[2]=computeTetra10RefBase(res+20,p); + computeWeightedCoeffsInTetra10FromRefBase(refCoo,bc); + break; + } + default: + throw INTERP_KERNEL::Exception("INTERP_KERNEL::barycentric_coords : unrecognized simplex !"); } } @@ -388,7 +566,7 @@ namespace INTERP_KERNEL } /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /*fonction pour vérifier qu'un point n'a pas déja été considérer dans */ + /*fonction pour verifier qu'un point n'a pas deja ete considerer dans */ /* le vecteur et le rajouter au vecteur sinon. */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ @@ -412,7 +590,7 @@ namespace INTERP_KERNEL /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ /* fonction qui rajoute les sommet du triangle P dans le vecteur V */ - /* si ceux-ci sont compris dans le triangle S et ne sont pas déjà dans */ + /* si ceux-ci sont compris dans le triangle S et ne sont pas deja dans */ /* V. */ /*sommets de P: P_1, P_2, P_3 */ /*sommets de S: P_4, P_5, P_6 */ @@ -439,7 +617,7 @@ namespace INTERP_KERNEL /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ /* calcul de l'intersection de deux segments: segments P1P2 avec P3P4 */ /* . Si l'intersection est non nulle et si celle-ci n'est */ - /* n'est pas déjà contenue dans Vect on la rajoute à Vect */ + /* n'est pas deja contenue dans Vect on la rajoute a Vect */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ inline void inters_de_segment(const double * P_1,const double * P_2, @@ -447,7 +625,7 @@ namespace INTERP_KERNEL std::vector& Vect, double dim_caracteristic, double precision) { - // calcul du déterminant de P_1P_2 et P_3P_4. + // calcul du determinant de P_1P_2 et P_3P_4. double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]); double absolute_precision = dim_caracteristic*precision; @@ -477,7 +655,7 @@ namespace INTERP_KERNEL /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ /* calcul l'intersection de deux triangles */ /* P_1, P_2, P_3: sommets du premier triangle */ - /* P_4, P_5, P_6: sommets du deuxième triangle */ + /* P_4, P_5, P_6: sommets du deuxi�me triangle */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3, @@ -498,7 +676,7 @@ namespace INTERP_KERNEL } /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* fonction pour vérifier qu'un n°de maille n'a pas déja été considérer */ + /* fonction pour verifier qu'un node maille n'a pas deja ete considerer */ /* dans le vecteur et le rajouter au vecteur sinon. */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ @@ -540,7 +718,7 @@ namespace INTERP_KERNEL /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction pour reconstituer un polygone convexe à partir */ + /* fonction pour reconstituer un polygone convexe a partir */ /* d'un nuage de point. */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ @@ -777,8 +955,8 @@ namespace INTERP_KERNEL /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ /* calcul l'intersection de deux polygones COPLANAIRES */ - /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considère*/ - /* que les deux premières coordonnées de chaque point */ + /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considere*/ + /* que les deux premieres coordonnees de chaque point */ /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ template inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, int nb_NodesA, int nb_NodesB, diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx index b7d381397..0720774ce 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.txx +++ b/src/INTERP_KERNEL/PlanarIntersector.txx @@ -384,7 +384,7 @@ namespace INTERP_KERNEL } else { - std::cout << " Maille dégénérée " << "epsilon = " << epsilon << std::endl; + std::cout << " Degenerated cell " << "epsilon = " << epsilon << std::endl; std::cout << " i_A1= " << i_A1 << " i_A2= " << i_A2 << std::endl; std::cout << " distance2(Coords_A,&Coords_A[i_A1])= " << distance2(Coords_A,&Coords_A[i_A1]) << std::endl; std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <::projectionThis(&CoordsS[0],littleTargetCell,3,3); diff --git a/src/INTERP_KERNEL/PointLocatorAlgos.txx b/src/INTERP_KERNEL/PointLocatorAlgos.txx index e05ef92c2..3c139887d 100644 --- a/src/INTERP_KERNEL/PointLocatorAlgos.txx +++ b/src/INTERP_KERNEL/PointLocatorAlgos.txx @@ -188,6 +188,7 @@ namespace INTERP_KERNEL { return isElementContainsPointAlg3D(ptToTest,conn_elem,conn_elem_sz,coords,cmType,eps); } + throw INTERP_KERNEL::Exception("Invalid spacedim detected ! Managed spaceDim are 2 and 3 !"); } bool elementContainsPoint(typename MyMeshType::MyConnType i, const double* x, double eps) diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.txx b/src/INTERP_KERNEL/PolygonAlgorithms.txx index 099212992..4b69884d2 100644 --- a/src/INTERP_KERNEL/PolygonAlgorithms.txx +++ b/src/INTERP_KERNEL/PolygonAlgorithms.txx @@ -78,17 +78,17 @@ namespace INTERP_KERNEL if(fabs(det) > _epsilon) { inv_det = 1/det; - t1=(AC[1]*DC[2]-AC[2]*DC[1])*inv_det; - t2=(AB[1]*AC[2]-AB[2]*AC[1])*inv_det; + t1=(AC[1]*DC[DIM-1]-AC[DIM-1]*DC[1])*inv_det; + t2=(AB[1]*AC[DIM-1]-AB[DIM-1]*AC[1])*inv_det; } else //beware AB and CD may belong to a plane y = constant { - det = AB[0]*DC[2]-AB[2]*DC[0]; + det = AB[0]*DC[DIM-1]-AB[DIM-1]*DC[0]; if(fabs(det) > _epsilon) { inv_det = 1/det; - t1=(AC[0]*DC[2]-AC[2]*DC[0])*inv_det; - t2=(AB[0]*AC[2]-AB[2]*AC[0])*inv_det; + t1=(AC[0]*DC[DIM-1]-AC[DIM-1]*DC[0])*inv_det; + t2=(AB[0]*AC[DIM-1]-AB[DIM-1]*AC[0])*inv_det; } else { diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx index 2bce00618..d1c07bf6c 100644 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx +++ b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx @@ -384,16 +384,16 @@ void ExprEvalInterpTest::testInterpreterUnit1() void ExprEvalInterpTest::testInterpreter3() { + std::set res; + double input[3]; + double res2[3]; INTERP_KERNEL::ExprParser expr1("2.3+x>5."); expr1.parse(); - std::set res; expr1.getSetOfVars(res); CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); CPPUNIT_ASSERT(*(res.begin())=="x"); expr1.prepareExprEvaluationVec(); - double input[3]; input[0]=0.; - double res2[3]; expr1.evaluateExpr(1,input,res2); CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); input[0]=2.8; @@ -436,6 +436,36 @@ void ExprEvalInterpTest::testInterpreter3() input[0]=2.6; expr3.evaluateExpr(1,input,res2); CPPUNIT_ASSERT_DOUBLES_EQUAL(9.8,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr4("if(x>1000,2*x,x/3)"); + expr4.parse(); + res.clear(); + expr4.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr4.prepareExprEvaluationVec(); + input[0]=2.7; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.9,res2[0],1e-12); + input[0]=999.; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(333.,res2[0],1e-12); + input[0]=1002.; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2004.,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr5("4.4*x*log10(x)*10"); + expr5.parse(); + res.clear(); + expr5.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr5.prepareExprEvaluationVec(); + input[0]=273.15; + expr5.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(29282.131520617437,res2[0],1e-9); + input[0]=0.; + CPPUNIT_ASSERT_THROW(expr5.evaluateExpr(1,input,res2),INTERP_KERNEL::Exception); } /*! @@ -455,3 +485,55 @@ void ExprEvalInterpTest::testInterpreter4() expr.evaluateExpr(1,vals, &result); CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2,result,1e-12); } + +/*! + * Allowing scientific format for floats. + */ +void ExprEvalInterpTest::testInterpreter5() +{ + std::set res; + double input[3]; + double res2[3]; + INTERP_KERNEL::ExprParser expr1("1.85e-3*x"); + expr1.parse(); + expr1.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr1.prepareExprEvaluationVec(); + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); + input[0]=-65.7; + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr2("x*1.85e-3"); + expr2.parse(); + expr2.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr2.prepareExprEvaluationVec(); + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); + input[0]=-65.7; + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr3("2.6E+1+x*1.85e-3"); + expr3.parse(); + expr3.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr3.prepareExprEvaluationVec(); + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.104895,res2[0],1e-12); + input[0]=-65.7; + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.878455,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr4("3.*max(((3.2e+1*(ln((2*5.2E-02+6.)+(1.2E-001*1.2E+2+3e-4))))),((3.2E-2*(exp((6e-1+2*5.2e-2)+(1.2E001*1.2+3.))))))"); + expr4.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6994207.8359543988,expr4.evaluate(),1e-5); +} diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx index b43050cb1..be789e8de 100644 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx +++ b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx @@ -38,6 +38,7 @@ namespace INTERP_TEST CPPUNIT_TEST( testInterpreterUnit1 ); CPPUNIT_TEST( testInterpreter3 ); CPPUNIT_TEST( testInterpreter4 ); + CPPUNIT_TEST( testInterpreter5 ); CPPUNIT_TEST_SUITE_END(); public: void setUp() { } @@ -50,6 +51,7 @@ namespace INTERP_TEST void testInterpreter2(); void testInterpreter3(); void testInterpreter4(); + void testInterpreter5(); void testInterpreterUnit0(); void testInterpreterUnit1(); }; diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx index 92281cdf3..8e03cac86 100644 --- a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx +++ b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx @@ -54,12 +54,12 @@ namespace INTERP_TEST const MEDMEM::SUPPORT *source_support=source_mesh->getSupportOnAll(MED_EN::MED_CELL); MEDMEM::FIELD *source_field=new FIELD(source_support,1); double* value=const_cast(source_field->getValue()); - for (int i=0; igetNumberOfElements(MED_EN::MED_ALL_ELEMENTS); i++) + for (int i=0; igetNumberOfElements(MED_EN::MEDMEM_ALL_ELEMENTS); i++) value[i]=1.0; const MEDMEM::SUPPORT *target_support=target_mesh->getSupportOnAll(MED_EN::MED_CELL); MEDMEM::FIELD *target_field=new FIELD(target_support,1); double* targetvalue=const_cast(target_field->getValue()); - for (int i=0; igetNumberOfElements(MED_EN::MED_ALL_ELEMENTS); i++) + for (int i=0; igetNumberOfElements(MED_EN::MEDMEM_ALL_ELEMENTS); i++) targetvalue[i]=0.0; // Ok at this point we have our mesh in MED-Memory format. // Go to wrap med_source_mesh and med_target_mesh. diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/src/INTERP_KERNELTest/MEDMeshMaker.cxx index c7eef5907..4f9df9e0a 100644 --- a/src/INTERP_KERNELTest/MEDMeshMaker.cxx +++ b/src/INTERP_KERNELTest/MEDMeshMaker.cxx @@ -17,27 +17,28 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +#include "MEDMeshMaker.hxx" + #include "MEDMEM_Mesh.hxx" #include "MEDMEM_Meshing.hxx" MEDMEM::MESH* MEDMeshMaker(int dim, int nbedge, MED_EN::medGeometryElement type) { MEDMEM::MESHING* mesh=new MEDMEM::MESHING(); - mesh->setSpaceDimension(dim); int nbnodes; int nbelems; switch (dim) { case 2: nbnodes=(nbedge+1)*(nbedge+1); - if(type==MED_EN::MED_QUAD4) + if(type==MED_EN::MEDMEM_QUAD4) nbelems=(nbedge*nbedge); else throw MEDMEM::MEDEXCEPTION("MEDMeshMaker: type not impletmented"); break; case 3: nbnodes=(nbedge+1)*(nbedge+1)*(nbedge+1); - if (type==MED_EN::MED_HEXA8) + if (type==MED_EN::MEDMEM_HEXA8) nbelems= nbedge*nbedge*nbedge; else throw MEDMEM::MEDEXCEPTION("MEDMeshMaker: type not impletmented"); @@ -94,8 +95,7 @@ MEDMEM::MESH* MEDMeshMaker(int dim, int nbedge, MED_EN::medGeometryElement type) conn [ielem*8+7]=ix*(nbedge+1)*(nbedge+1)+(iy+1)*(nbedge+1)+iz+1+1; } } - mesh->setConnectivity(conn, MED_EN::MED_CELL,type); + mesh->setConnectivity(MED_EN::MED_CELL,type,conn); delete [] conn; - mesh->setMeshDimension(dim); return mesh; } diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.txx b/src/INTERP_KERNELTest/MeshTestToolkit.txx index abbac662a..33523aa3a 100644 --- a/src/INTERP_KERNELTest/MeshTestToolkit.txx +++ b/src/INTERP_KERNELTest/MeshTestToolkit.txx @@ -119,7 +119,7 @@ namespace INTERP_TEST break; } const double *tabS = f->getValue(); - std::copy(tabS,tabS+mesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS),tab); + std::copy(tabS,tabS+mesh.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS),tab); f->removeReference(); } @@ -168,10 +168,10 @@ namespace INTERP_TEST bool ok = true; // source elements - double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; + double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS)]; getVolumes(sMesh, sVol); - for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) + for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS); ++i) { const double sum_row = sumRow(m, i+1); if(!epsilonEqualRelative(sum_row, fabs(sVol[i]), _precision)) @@ -183,9 +183,9 @@ namespace INTERP_TEST } // target elements - double* tVol = new double[tMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; + double* tVol = new double[tMesh.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS)]; getVolumes(tMesh, tVol); - for(int i = 0; i < tMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) + for(int i = 0; i < tMesh.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS); ++i) { const double sum_col = sumCol(m, i); if(!epsilonEqualRelative(sum_col,fabs(tVol[i]), _precision)) diff --git a/src/INTERP_KERNELTest/PointLocatorTest.cxx b/src/INTERP_KERNELTest/PointLocatorTest.cxx index 8cdc16274..c63f54d8c 100644 --- a/src/INTERP_KERNELTest/PointLocatorTest.cxx +++ b/src/INTERP_KERNELTest/PointLocatorTest.cxx @@ -47,7 +47,7 @@ namespace INTERP_TEST * a bbox overlapping the bboxes of the tree */ void PointLocatorTest::test_PointLocator() { - MEDMEM::MESH* mesh2D= MEDMeshMaker(2,2,MED_EN::MED_QUAD4); + MEDMEM::MESH* mesh2D= MEDMeshMaker(2,2,MED_EN::MEDMEM_QUAD4); MEDMEM::PointLocator pl(*mesh2D) ; double x[2]={0.0,0.0}; std::list elems = pl.locate(x); @@ -72,7 +72,7 @@ namespace INTERP_TEST elems.clear(); delete mesh2D; - MEDMEM::MESH* mesh3D= MEDMeshMaker(3,2,MED_EN::MED_HEXA8); + MEDMEM::MESH* mesh3D= MEDMeshMaker(3,2,MED_EN::MEDMEM_HEXA8); MEDMEM::PointLocator pl3(*mesh3D); double xx[3]={0.0,0.0,0.0}; elems = pl3.locate(xx); @@ -108,7 +108,7 @@ namespace INTERP_TEST */ void PointLocatorTest::test_PointLocatorInSimplex() { - MEDMEM::MESH* mesh2D= MEDMeshMaker(2,2,MED_EN::MED_QUAD4); + MEDMEM::MESH* mesh2D= MEDMeshMaker(2,2,MED_EN::MEDMEM_QUAD4); // mesh is a quadrangle (0.0-1.0 x 0.0-1.0 ) // 3 -- 6 -- 9 // | | | @@ -160,7 +160,7 @@ namespace INTERP_TEST CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); delete mesh2D; } - MEDMEM::MESH* mesh3D= MEDMeshMaker(3,2,MED_EN::MED_HEXA8); + MEDMEM::MESH* mesh3D= MEDMeshMaker(3,2,MED_EN::MEDMEM_HEXA8); // ^Z // | // 3 -- 6 -- 9 diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index a5dbae15b..9497a918a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -213,6 +213,22 @@ void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) } } +void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + if(_x_array) + _x_array->checkMonotonic(eps); + if(_y_array) + _y_array->checkMonotonic(eps); + if(_z_array) + _z_array->checkMonotonic(eps); +} + +void MEDCouplingCMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + int MEDCouplingCMesh::getNumberOfCells() const { int ret=1; @@ -396,7 +412,22 @@ std::string MEDCouplingCMesh::advancedRepr() const return simpleRepr(); } -DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) +const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) +{ + switch(i) + { + case 0: + return _x_array; + case 1: + return _y_array; + case 2: + return _z_array; + default: + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + } +} + +DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception) { switch(i) { @@ -411,7 +442,7 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL: } } -void MEDCouplingCMesh::setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) +void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) { DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; if(i<0 || i>2) @@ -420,33 +451,70 @@ void MEDCouplingCMesh::setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KER { if(*(thisArr[i])) (*(thisArr[i]))->decrRef(); - (*(thisArr[i]))=arr; + (*(thisArr[i]))=const_cast(arr); if(*(thisArr[i])) (*(thisArr[i]))->incrRef(); declareAsNew(); } } -void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coordsY, DataArrayDouble *coordsZ) +void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) { if(_x_array) _x_array->decrRef(); - _x_array=coordsX; + _x_array=const_cast(coordsX); if(_x_array) _x_array->incrRef(); if(_y_array) _y_array->decrRef(); - _y_array=coordsY; + _y_array=const_cast(coordsY); if(_y_array) _y_array->incrRef(); if(_z_array) _z_array->decrRef(); - _z_array=coordsZ; + _z_array=const_cast(coordsZ); if(_z_array) _z_array->incrRef(); declareAsNew(); } +/*! + * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information + */ +DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + int sz=code.size(); + if(sz!=0 && sz!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 2 exactly !"); + if(code[0]==INTERP_KERNEL::NORM_ERROR) + { + int nbNodes=getNumberOfNodes(); + if(code[2]==-1) + { + if(code[1]==nbNodes) + return 0; + else + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of nodes mismatch !"); + } + else + idsPerType[code[2]]->deepCpy(); + } + else + { + 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 + idsPerType[code[2]]->deepCpy(); + } + return 0; +} + MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) { int spaceDim=getSpaceDimension(); @@ -498,7 +566,7 @@ void MEDCouplingCMesh::getBoundingBox(double *bbox) const int j=0; for (int idim=0; idimgetConstPointer(); @@ -639,7 +707,7 @@ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const double *pt=ret->getPointer(); int tmp[3]; getSplitNodeValues(tmp); - DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; const double *tabsPtr[3]; for(int j=0;jgetPointer(); int tmp[3]; getSplitCellValues(tmp); - DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; std::vector tabsPtr[3]; for(int j=0;j& coo) const; std::string simpleRepr() const; std::string advancedRepr() const; - DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception); - void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); - void setCoords(DataArrayDouble *coordsX, - DataArrayDouble *coordsY=0, - DataArrayDouble *coordsZ=0); + const DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getCoordsAt(int i) throw(INTERP_KERNEL::Exception); + void setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); + void setCoords(const DataArrayDouble *coordsX, + const DataArrayDouble *coordsY=0, + const DataArrayDouble *coordsZ=0); // tools + DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const 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; diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 991856018..70e880883 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -292,6 +292,16 @@ void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Excep { } +void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); +} + +void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const { double bbox2D[6]; @@ -582,6 +592,11 @@ void MEDCouplingExtrudedMesh::scale(const double *point, double factor) _mesh1D->scale(point,factor); } +DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const { // not implemented yet ! diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index be0937cb1..e8a271e5b 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -58,6 +58,8 @@ namespace ParaMEDMEM std::string simpleRepr() const; std::string advancedRepr() const; 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); void getBoundingBox(double *bbox) const; void updateTime() const; void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); @@ -77,6 +79,7 @@ namespace ParaMEDMEM void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); void scale(const double *point, double factor); + DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) 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); diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 6ba066f22..b9f457d36 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -721,6 +721,8 @@ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTE void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception) { const DataArrayDouble *arr=_time_discr->getArray(); + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnPos"); _type->getValueOnPos(arr,_mesh,i,j,k,res); } @@ -731,6 +733,8 @@ void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) con void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception) { const DataArrayDouble *arr=_time_discr->getArray(); + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); _type->getValueOn(arr,_mesh,spaceLoc,res); } @@ -740,6 +744,8 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) con DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception) { const DataArrayDouble *arr=_time_discr->getArray(); + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOnMulti"); return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints); } @@ -751,6 +757,8 @@ DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception) { std::vector< const DataArrayDouble *> arrs=_time_discr->getArraysForTime(time); + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform getValueOn"); std::vector res2; for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) { diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 80c2aa6a6..75c857862 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -244,7 +244,7 @@ void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception) if(!ptr) throw INTERP_KERNEL::Exception("DataArrayDouble::iota : allocate first !"); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component!"); + throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); int ntuples=getNumberOfTuples(); for(int i=0;i 0 !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + int newNbOfTuples=(end-bg)/step; + ret->alloc(newNbOfTuples,nbComp); + double *pt=ret->getPointer(); + const double *srcPt=getConstPointer()+bg*nbComp; + for(int i=0;icopyStringInfoFrom(*this); + ret->incrRef(); + return ret; +} + /*! * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components. * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept. @@ -587,6 +636,12 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); int newNbOfCompo=compoIds.size(); int oldNbOfCompo=getNumberOfComponents(); + for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) + if((*it)<0 || (*it)>=oldNbOfCompo) + { + std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } int nbOfTuples=getNumberOfTuples(); ret->alloc(nbOfTuples,newNbOfCompo); ret->copyPartOfStringInfoFrom(*this,compoIds); @@ -675,7 +730,7 @@ void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception) double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); int nbOfTuples=getNumberOfTuples(); if(nbOfTuples<=0) throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !"); @@ -697,7 +752,7 @@ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); int nbOfTuples=getNumberOfTuples(); if(nbOfTuples<=0) throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); @@ -719,7 +774,7 @@ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); int nbOfTuples=getNumberOfTuples(); if(nbOfTuples<=0) throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !"); @@ -1755,7 +1810,7 @@ void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception) if(!ptr) throw INTERP_KERNEL::Exception("DataArrayInt::iota : allocate first !"); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component!"); + throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); int ntuples=getNumberOfTuples(); for(int i=0;i 0 !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + int newNbOfTuples=(end-bg)/step; + ret->alloc(newNbOfTuples,nbComp); + int *pt=ret->getPointer(); + const int *srcPt=getConstPointer()+bg*nbComp; + for(int i=0;icopyStringInfoFrom(*this); + ret->incrRef(); + return ret; +} + /*! * 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]. @@ -2147,7 +2226,7 @@ bool DataArrayInt::isIdentity() const bool DataArrayInt::isUniform(int val) const { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); int nbOfTuples=getNumberOfTuples(); const int *w=getConstPointer(); const int *end=w+nbOfTuples; @@ -2260,6 +2339,12 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compo MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); int newNbOfCompo=compoIds.size(); int oldNbOfCompo=getNumberOfComponents(); + for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) + if((*it)<0 || (*it)>=oldNbOfCompo) + { + std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } int nbOfTuples=getNumberOfTuples(); ret->alloc(nbOfTuples,newNbOfCompo); ret->copyPartOfStringInfoFrom(*this,compoIds); @@ -2331,7 +2416,7 @@ void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component !"); + 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; int nbOfTuples=getNumberOfTuples(); @@ -2347,7 +2432,7 @@ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exce DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component !"); + 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; int nbOfTuples=getNumberOfTuples(); @@ -2363,7 +2448,7 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E DataArrayInt *DataArrayInt::getIdsEqualList(const std::vector& vals) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); std::set vals2(vals.begin(),vals.end()); const int *cptr=getConstPointer(); std::vector res; @@ -2380,7 +2465,7 @@ DataArrayInt *DataArrayInt::getIdsEqualList(const std::vector& vals) const DataArrayInt *DataArrayInt::getIdsNotEqualList(const std::vector& vals) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); std::set vals2(vals.begin(),vals.end()); const int *cptr=getConstPointer(); std::vector res; diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 4bf9f4a78..64d50d6c8 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -132,6 +132,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void iota(double init=0.) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const; MEDCOUPLING_EXPORT void sort() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkMonotonic(double eps) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isMonotonic(double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string repr() const; MEDCOUPLING_EXPORT std::string reprZip() const; MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; @@ -152,6 +154,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const; MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId2(int bg, int end, int step) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); @@ -264,6 +267,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; MEDCOUPLING_EXPORT DataArrayInt *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) 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 bool isIdentity() const; diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index cdb0cfdf4..e57d26698 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -199,6 +199,18 @@ void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(IN _time_unit=other->_time_unit; } +/*! + * This method copies all attributes that are \b NOT arrays in this. + * All tiny attributes not usefully for state of 'this' are ignored. + */ +void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + copyTinyStringsFrom(other); + _time=other->_time; + _iteration=other->_iteration; + _order=other->_order; +} + /*! * This method builds a field lying on 'this' with 'nbOfComp' components. * 'func' is a string that is the expression to evaluate. diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 6303f0fe5..4e7fdf990 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -58,6 +58,7 @@ namespace ParaMEDMEM virtual MEDCouplingMeshType getType() const = 0; bool isStructured() const; virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); // comparison methods virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; @@ -70,6 +71,8 @@ namespace ParaMEDMEM DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); // virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfCells() const = 0; virtual int getNumberOfNodes() const = 0; virtual int getSpaceDimension() const = 0; @@ -84,6 +87,7 @@ namespace ParaMEDMEM virtual std::string simpleRepr() const = 0; virtual std::string advancedRepr() const = 0; // tools + virtual DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) = 0; virtual void getBoundingBox(double *bbox) const = 0; virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0; diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx index e279727d3..902efb2a8 100644 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx @@ -42,7 +42,7 @@ void MEDCouplingNormalizedUnstructuredMesh::getBoundingBox(dou boundingBox[i]=std::numeric_limits::max(); boundingBox[SPACEDIM+i]=-std::numeric_limits::max(); } - ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); const double *ptr=array->getConstPointer(); int nbOfPts=array->getNbOfElems()/SPACEDIM; for(int j=0;j::getConnectiv template const double *MEDCouplingNormalizedUnstructuredMesh::getCoordinatesPtr() const { - ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); return array->getConstPointer(); } diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 816023a9b..588013a2c 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -73,13 +73,13 @@ void MEDCouplingPointSet::updateTime() const } } -void MEDCouplingPointSet::setCoords(DataArrayDouble *coords) +void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) { if( coords != _coords ) { if (_coords) _coords->decrRef(); - _coords=coords; + _coords=const_cast(coords); if(_coords) _coords->incrRef(); declareAsNew(); @@ -642,7 +642,7 @@ void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) con { if(_coords) { - a2=getCoords(); + a2=const_cast(getCoords()); a2->incrRef(); } else diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index f18a77b0f..7367d9ca8 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -45,8 +45,9 @@ namespace ParaMEDMEM void updateTime() const; int getNumberOfNodes() const; int getSpaceDimension() const; - void setCoords(DataArrayDouble *coords); - DataArrayDouble *getCoords() const { return _coords; } + void setCoords(const DataArrayDouble *coords); + const DataArrayDouble *getCoords() const { return _coords; } + DataArrayDouble *getCoords() { return _coords; } DataArrayDouble *getCoordinatesAndOwner() const; void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqual(const MEDCouplingMesh *other, double prec) const; diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx index 0fc9fc3fb..648c58e48 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ b/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -20,6 +20,7 @@ #include "MEDCouplingRemapper.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" #include "MEDCouplingFieldDiscretization.hxx" #include "MEDCouplingExtrudedMesh.hxx" #include "MEDCouplingNormalizedUnstructuredMesh.txx" @@ -44,7 +45,7 @@ MEDCouplingRemapper::~MEDCouplingRemapper() int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception) { releaseData(true); - _src_mesh=(MEDCouplingMesh *)srcMesh; _target_mesh=(MEDCouplingMesh *)targetMesh; + _src_mesh=const_cast(srcMesh); _target_mesh=const_cast(targetMesh); _src_mesh->incrRef(); _target_mesh->incrRef(); int meshInterpType=((int)_src_mesh->getType()*16)+(int)_target_mesh->getType(); switch(meshInterpType) @@ -58,6 +59,13 @@ int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCoupli } } +int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception) +{ + std::string meth(src->getDiscretization()->getStringRepr()); + meth+=target->getDiscretization()->getStringRepr(); + return prepare(src->getMesh(),target->getMesh(),meth.c_str()); +} + void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { if(_src_method!=srcField->getDiscretization()->getStringRepr()) diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx index 07d2be0a0..7946a7a7c 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ b/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -34,6 +34,7 @@ namespace ParaMEDMEM class MEDCouplingMesh; class MEDCouplingUMesh; class MEDCouplingFieldDouble; + class MEDCouplingFieldTemplate; } namespace ParaMEDMEM @@ -44,6 +45,7 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper(); MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper(); MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception); + MEDCOUPLINGREMAPPER_EXPORT int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 0319b3b84..a654f65b4 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -119,6 +119,72 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) } } +/*! + * This method performs deeper checking in 'this' than MEDCouplingUMesh::checkCoherency does. + * So this method is more time-consuming. This method checks that nodal connectivity points to valid node ids. + * No geometrical aspects are checked here. These aspects are done in MEDCouplingUMesh::checkCoherency2. + */ +void MEDCouplingUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + if(_mesh_dim==-1) + return ; + int meshDim=getMeshDimension(); + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells(); + const int *ptr=_nodal_connec->getConstPointer(); + const int *ptrI=_nodal_connec_index->getConstPointer(); + for(int i=0;i=0) + { + if(nodeId>=nbOfNodes) + { + std::ostringstream oss; oss << "Cell #" << i << " has is consituted of node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else if(nodeId<-1) + { + std::ostringstream oss; oss << "Cell #" << i << " has is consituted of node #" << nodeId << " in connectivity ! sounds bad !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { + if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED) + { + std::ostringstream oss; oss << "Cell #" << i << " has is consituted of node #-1 in connectivity ! sounds bad !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } +} + +void MEDCouplingUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + void MEDCouplingUMesh::setMeshDimension(int meshDim) { if(meshDim<-1) @@ -642,6 +708,13 @@ void MEDCouplingUMesh::unPolyze() posOfCurCell=index[i+1]; index[i+1]=newPos; } + else + { + std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos); + newPos+=lgthOfCurCell; + posOfCurCell+=lgthOfCurCell; + index[i+1]=newPos; + } } if(newPos!=initMeshLgth) _nodal_connec->reAlloc(newPos); @@ -980,7 +1053,7 @@ DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerg */ void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) { - DataArrayDouble *coords=other.getCoords(); + const DataArrayDouble *coords=other.getCoords(); if(!coords) throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !"); if(!_coords) @@ -1763,17 +1836,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin { checkFullyDefined(); MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - std::string name(getName()); - int sz=strlen(PART_OF_NAME); - if((int)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->_mesh_dim=_mesh_dim; ret->setCoords(_coords); int nbOfElemsRet=end-begin; @@ -1800,6 +1862,18 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin ret->_types=types; connRetArr->decrRef(); connIndexRetArr->decrRef(); + ret->copyTinyInfoFrom(this); + std::string name(getName()); + int sz=strlen(PART_OF_NAME); + if((int)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()); return ret; } @@ -3241,6 +3315,88 @@ namespace ParaMEDMEMImpl const int *_conn; int _val; }; + + class ConnReader2 + { + public: + ConnReader2(const int *c, int val):_conn(c),_val(val) { } + bool operator() (const int& pos) { return _conn[pos]==_val; } + private: + const int *_conn; + int _val; + }; +} + +/*! + * This method is used to check that this has contiguous cell type in same order than described in 'code'. + * Format of 'code' is the following. 'code' should be of size 3*n and non empty. If not an exception is thrown. + * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k. + * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array. + * If 2 or more same geometric type is in 'code' and exception is thrown too. + * + * This method fistly checks + * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown. + * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match, + * an exception is thrown too. + * + * If all geometric types in 'code' are exactly those in 'this' null pointer is returned. + * If it exists a geometric type in 'this' \b not in 'code' \b no exception is thrown and a DataArrayInt instance is returned that the user as the responsability + * to deallocate. + */ +DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + if(code.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !"); + int sz=code.size(); + std::size_t n=sz/3; + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT even !"); + std::vector types; + int nb=0; + for(std::size_t i=0;ialloc(nb,1); + int *retPtr=ret->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + int nbOfCells=getNumberOfCells(); + const int *i=connI; + int kk=0; + for(std::vector::const_iterator it=types.begin();it!=types.end();it++,kk++) + { + i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it))); + int offset=std::distance(connI,i); + if(code[3*kk+2]==-1) + { + const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); + int pos2=std::distance(i,j); + for(int k=0;kgetConstPointer(),idsPerType[code[3*kk+2]]->getConstPointer()+idsPerType[code[3*kk+2]]->getNbOfElems(), + retPtr,std::bind2nd(std::plus(),offset)); + } + } + return ret; } /*! @@ -3451,7 +3607,7 @@ DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *d * cells whose ids is in 'idsPerGeoType' array. * This method conserves coords and name of mesh. */ -MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const std::vector& idsPerGeoType) const +MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const { std::vector idsTokeep; int nbOfCells=getNumberOfCells(); @@ -3461,7 +3617,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized idsTokeep.push_back(i); else { - if(std::find(idsPerGeoType.begin(),idsPerGeoType.end(),j)!=idsPerGeoType.end()) + if(std::find(idsPerGeoTypeBg,idsPerGeoTypeEnd,j)!=idsPerGeoTypeEnd) idsTokeep.push_back(i); j++; } @@ -3472,8 +3628,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized ret->decrRef(); return 0; } - ret2->setName(getName()); - ret2->setDescription(getDescription()); + ret2->copyTinyInfoFrom(this); return ret2; } @@ -3660,7 +3815,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vectorgetCoords(); + const DataArrayDouble *coords=meshes.front()->getCoords(); int meshDim=meshes.front()->getMeshDimension(); std::vector::const_iterator iter=meshes.begin(); int meshLgth=0; diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index ad61c5186..cb4c35d45 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -45,6 +45,8 @@ namespace ParaMEDMEM DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setMeshDimension(int meshDim); MEDCOUPLING_EXPORT void allocateCells(int nbOfCells); MEDCOUPLING_EXPORT void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) throw(INTERP_KERNEL::Exception); @@ -52,8 +54,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT const std::set& getAllTypes() const { return _types; } MEDCOUPLING_EXPORT std::set getTypesOfPart(const int *begin, const int *end) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } + MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } + MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() { return _nodal_connec; } + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() { return _nodal_connec_index; } MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; @@ -134,6 +138,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); //utilities for MED File RW + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; @@ -141,7 +146,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT std::vector splitByType() const; MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const std::vector& idsPerGeoType) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; // MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 877b7e2c6..da362d0a2 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -25,7 +25,7 @@ using namespace ParaMEDMEM; -MEDCouplingUMeshDesc::MEDCouplingUMeshDesc():_mesh_dim(-1),_desc_connec(0),_desc_connec_index(0), +MEDCouplingUMeshDesc::MEDCouplingUMeshDesc():_mesh_dim(-2),_desc_connec(0),_desc_connec_index(0), _nodal_connec_face(0),_nodal_connec_face_index(0) { } @@ -76,6 +76,16 @@ void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception } } +void MEDCouplingUMeshDesc::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); +} + +void MEDCouplingUMeshDesc::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + void MEDCouplingUMeshDesc::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) { @@ -174,6 +184,11 @@ void MEDCouplingUMeshDesc::setConnectivity(DataArrayInt *descConn, DataArrayInt computeTypes(); } +DataArrayInt *MEDCouplingUMeshDesc::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + void MEDCouplingUMeshDesc::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const { MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings); @@ -190,7 +205,7 @@ bool MEDCouplingUMeshDesc::isEmptyMesh(const std::vector& tinyInfo) const return tinyInfo[5]<=0; } -void MEDCouplingUMeshDesc::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) +void MEDCouplingUMeshDesc::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const { std::vector tinyInfoTmp(tinyInfo.begin()+1,tinyInfo.end()); MEDCouplingPointSet::resizeForUnserialization(tinyInfoTmp,a1,a2,littleStrings); @@ -214,7 +229,7 @@ void MEDCouplingUMeshDesc::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) co std::copy(faceConnIndex,faceConnIndex+getNumberOfFaces()+1,ptA1); } -void MEDCouplingUMeshDesc::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) +void MEDCouplingUMeshDesc::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) { std::vector tinyInfoTmp(tinyInfo.begin()+1,tinyInfo.end()); MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfoTmp,a1,a2,littleStrings); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index c83a1ec71..a0f7ca5f0 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -35,6 +35,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim); 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); + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, @@ -54,11 +56,12 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED_DESC; } MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx); //tools to overload + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings); + 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, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); + 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); MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); @@ -86,7 +89,7 @@ namespace ParaMEDMEM void computeTypes(); void checkFullyDefined() const throw(INTERP_KERNEL::Exception); private: - unsigned _mesh_dim; + int _mesh_dim; DataArrayInt *_desc_connec; DataArrayInt *_desc_connec_index; DataArrayInt *_nodal_connec_face; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 9b1a81a75..3691ac64c 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -205,11 +205,15 @@ namespace ParaMEDMEM CPPUNIT_TEST( testFillFromAnalyticThree1 ); CPPUNIT_TEST( testDAUnitVar1 ); CPPUNIT_TEST( testGaussCoordinates1 ); - //CPPUNIT_TEST( testP2Localization1 ); not implemented yet + CPPUNIT_TEST( testP2Localization1 ); + CPPUNIT_TEST( testP2Localization2 ); CPPUNIT_TEST( testGetValueOn2 ); CPPUNIT_TEST( testDAIGetIdsNotEqual1 ); CPPUNIT_TEST( testDAIComputeOffsets1 ); CPPUNIT_TEST( testUMeshHexagonPrism1 ); + CPPUNIT_TEST( testDADCheckIsMonotonic ); + CPPUNIT_TEST( testCheckCoherencyDeeper1 ); + CPPUNIT_TEST( testUnPolyze2 ); //MEDCouplingBasicsTestInterp.cxx CPPUNIT_TEST( test2DInterpP0P0_1 ); CPPUNIT_TEST( test2DInterpP0P0PL_1 ); @@ -440,11 +444,16 @@ namespace ParaMEDMEM void testFillFromAnalyticThree1(); void testDAUnitVar1(); void testGaussCoordinates1(); + void testQ1Localization1(); void testP2Localization1(); + void testP2Localization2(); void testGetValueOn2(); void testDAIGetIdsNotEqual1(); void testDAIComputeOffsets1(); void testUMeshHexagonPrism1(); + void testDADCheckIsMonotonic(); + void testCheckCoherencyDeeper1(); + void testUnPolyze2(); //MEDCouplingBasicsTestInterp.cxx void test2DInterpP0P0_1(); void test2DInterpP0P0PL_1(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index 2f63bfa0c..017cb95eb 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -619,9 +619,9 @@ void MEDCouplingBasicsTest::testGaussCoordinates1() } /*! - * Not activated test ! To be implemented ! WARNING Hexa8 should be replaced by Quad8... + * Not activated test ! To be implemented ! */ -void MEDCouplingBasicsTest::testP2Localization1() +void MEDCouplingBasicsTest::testQ1Localization1() { MEDCouplingUMesh *m=buildHexa8Mesh_1(); MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); @@ -642,6 +642,74 @@ void MEDCouplingBasicsTest::testP2Localization1() m->decrRef(); } +void MEDCouplingBasicsTest::testP2Localization1() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2",2); + const double coords[12]={0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4}; + const int conn[6]={0,1,2,3,4,5}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(6,2); + std::copy(coords,coords+12,coo->getPointer()); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn); + m->finishInsertingCells(); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f->setMesh(m); + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,3); + const double vals1[18]={1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4}; + std::copy(vals1,vals1+18,da->getPointer()); + f->setArray(da); + da->decrRef(); + // + const double loc[2]={2.27,1.3}; + DataArrayDouble *locs=f->getValueOnMulti(loc,1); + const double expected1[3]={6.0921164547752236, 7.1921164547752232, 8.2921164547752255}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); + locs->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest::testP2Localization2() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2_2",3); + const double coords[30]={0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891}; + const int conn[10]={0,1,2,3,4,5,6,7,8,9}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(10,3); + std::copy(coords,coords+30,coo->getPointer()); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn); + m->finishInsertingCells(); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f->setMesh(m); + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(10,1); + const double vals1[10]={1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2}; + std::copy(vals1,vals1+10,da->getPointer()); + f->setArray(da); + da->decrRef(); + // + const double loc[3]={0.64637931739890486, -0.16185896817550552, 0.22678966365273748}; + DataArrayDouble *locs=f->getValueOnMulti(loc,1); + const double expected1[1]={10.0844021968047}; + for(int i=0;i<1;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); + locs->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + void MEDCouplingBasicsTest::testGetValueOn2() { MEDCouplingUMesh *m=build2DTargetMesh_1(); @@ -791,3 +859,100 @@ void MEDCouplingBasicsTest::testUMeshHexagonPrism1() bary->decrRef(); mesh->decrRef(); } + +void MEDCouplingBasicsTest::testDADCheckIsMonotonic() +{ + DataArrayDouble *da=DataArrayDouble::New(); + const double vals[4]={-1.,1.01,2.03,6.}; + da->alloc(2,2); + std::copy(vals,vals+4,da->getPointer()); + CPPUNIT_ASSERT_THROW(da->isMonotonic(1e-12),INTERP_KERNEL::Exception); + da->rearrange(1); + CPPUNIT_ASSERT(da->isMonotonic(1e-12)); + da->checkMonotonic(1e-12); + da->setIJ(2,0,6.1); + CPPUNIT_ASSERT(!da->isMonotonic(1e-12)); + CPPUNIT_ASSERT_THROW(da->checkMonotonic(1e-12),INTERP_KERNEL::Exception); + da->setIJ(2,0,5.99); + CPPUNIT_ASSERT(da->isMonotonic(1e-12)); + CPPUNIT_ASSERT(!da->isMonotonic(1e-1)); + da->decrRef(); +} + +void MEDCouplingBasicsTest::testCheckCoherencyDeeper1() +{ + MEDCouplingUMesh *m=build3DSourceMesh_1(); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(8,0,-1); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,-6); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,9);//9>=NbOfNodes + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,8);//OK + m->checkCoherency(); + m->checkCoherency1(); + const int elts[2]={1,5}; + std::vector eltsV(elts,elts+2); + m->convertToPolyTypes(eltsV); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(2,0,9);//9>=NbOfNodes + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(2,0,-3); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(2,0,-1); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw because cell#0 is not a polyhedron + m->getNodalConnectivity()->setIJ(2,0,4); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(7,0,-1); + m->checkCoherency(); + m->checkCoherency1();//OK because we are in polyhedron connec + m->getNodalConnectivity()->setIJ(36,0,14); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. + m->decrRef(); +} + +void MEDCouplingBasicsTest::testUnPolyze2() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("jjj",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(4,3); + coo->rearrange(1); + coo->iota(0); + coo->rearrange(3); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(2); + const int conn[4]={0,1,2,3}; + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + m->finishInsertingCells(); + std::vector ms(4,m); + MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms); + std::vector temp(1,2); + m2->convertToPolyTypes(temp); + m2->unPolyze(); + CPPUNIT_ASSERT(INTERP_KERNEL::NORM_TETRA4==m2->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(40,m2->getMeshLength()); + std::vector temp2; + m2->getNodeIdsOfCell(2,temp2); + CPPUNIT_ASSERT(4==(int)temp2.size()); + CPPUNIT_ASSERT(std::equal(conn,conn+4,temp2.begin())); + m2->checkCoherency1(); + MEDCouplingMesh *m3=m2->deepCpy(); + m2->unPolyze(); + CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); + m3->decrRef(); + m->decrRef(); + m2->decrRef(); +} diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx index 1050f75ce..d1b1daed8 100644 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx +++ b/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx @@ -21,6 +21,7 @@ #include "MEDCouplingUMesh.hxx" #include "MEDCouplingExtrudedMesh.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingRemapper.hxx" @@ -982,6 +983,44 @@ void MEDCouplingRemapperTest::testExtruded2() meshTF->decrRef(); } +void MEDCouplingRemapperTest::testPrepareEx1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + MEDCouplingFieldTemplate *srcFt=MEDCouplingFieldTemplate::New(ON_CELLS); + MEDCouplingFieldTemplate *trgFt=MEDCouplingFieldTemplate::New(ON_CELLS); + srcFt->setMesh(sourceMesh); + trgFt->setMesh(targetMesh); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepareEx(srcFt,trgFt)); + srcFt->decrRef(); + trgFt->decrRef(); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;igetNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + MEDCouplingUMesh *MEDCouplingRemapperTest::build1DTargetMesh_2() { double targetCoords[20]={ diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx index 2b45b4b06..51fad76ca 100644 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx @@ -40,6 +40,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testNatureOfField ); CPPUNIT_TEST( testExtruded ); CPPUNIT_TEST( testExtruded2 ); + CPPUNIT_TEST( testPrepareEx1 ); CPPUNIT_TEST_SUITE_END(); public: void test2DInterpP0P0_1(); @@ -50,6 +51,7 @@ namespace ParaMEDMEM void testNatureOfField(); void testExtruded(); void testExtruded2(); + void testPrepareEx1(); private: static MEDCouplingUMesh *build1DTargetMesh_2(); static MEDCouplingUMesh *build2DTargetMesh_3(); diff --git a/src/MEDCoupling/Test/TestMEDCoupling.cxx b/src/MEDCoupling/Test/TestMEDCoupling.cxx index 84813ca08..b627e509a 100644 --- a/src/MEDCoupling/Test/TestMEDCoupling.cxx +++ b/src/MEDCoupling/Test/TestMEDCoupling.cxx @@ -17,7 +17,6 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "CppUnitTest.hxx" #include "MEDCouplingBasicsTest.hxx" CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest ); diff --git a/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx b/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx index 80b233001..5037f4f0c 100644 --- a/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx +++ b/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx @@ -17,7 +17,6 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "CppUnitTest.hxx" #include "MEDCouplingRemapperTest.hxx" CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingRemapperTest ); diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index fc690e156..2a68c9612 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -121,6 +121,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::keepSelectedComponents; %newobject ParaMEDMEM::DataArrayInt::selectByTupleId; %newobject ParaMEDMEM::DataArrayInt::selectByTupleIdSafe; +%newobject ParaMEDMEM::DataArrayInt::selectByTupleId2; %newobject ParaMEDMEM::DataArrayInt::checkAndPreparePermutation; %newobject ParaMEDMEM::DataArrayInt::renumber; %newobject ParaMEDMEM::DataArrayInt::renumberR; @@ -143,6 +144,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::buildIntersection; %newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex; %newobject ParaMEDMEM::DataArrayInt::buildPermutationArr; +%newobject ParaMEDMEM::DataArrayInt::__getitem__; %newobject ParaMEDMEM::DataArrayDouble::New; %newobject ParaMEDMEM::DataArrayDouble::convertToIntArr; %newobject ParaMEDMEM::DataArrayDouble::deepCpy; @@ -161,6 +163,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; %newobject ParaMEDMEM::DataArrayDouble::selectByTupleId; %newobject ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe; +%newobject ParaMEDMEM::DataArrayDouble::selectByTupleId2; %newobject ParaMEDMEM::DataArrayDouble::applyFunc; %newobject ParaMEDMEM::DataArrayDouble::applyFunc2; %newobject ParaMEDMEM::DataArrayDouble::applyFunc3; @@ -181,7 +184,9 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayDouble::fromPolarToCart; %newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; %newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; +%newobject ParaMEDMEM::DataArrayDouble::__getitem__; %newobject ParaMEDMEM::MEDCouplingMesh::deepCpy; +%newobject ParaMEDMEM::MEDCouplingMesh::checkTypeConsistencyAndContig; %newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner; %newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner; %newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField; @@ -245,7 +250,6 @@ using namespace INTERP_KERNEL; %rename(assign) *::operator=; %ignore ParaMEDMEM::MemArray::operator=; %ignore ParaMEDMEM::MemArray::operator[]; -%ignore ParaMEDMEM::MEDCouplingPointSet::getCoords(); %ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo; %ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; @@ -300,7 +304,10 @@ namespace ParaMEDMEM virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) = 0; virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception) = 0; virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception) = 0; @@ -496,6 +503,15 @@ namespace ParaMEDMEM return res; } + DataArrayInt *checkTypeConsistencyAndContig(PyObject *li, PyObject *li2) const throw(INTERP_KERNEL::Exception) + { + std::vector code; + std::vector idsPerType; + convertPyObjToVecDataArrayIntCst(li2,idsPerType); + convertPyToNewIntArr3(li,code); + return self->checkTypeConsistencyAndContig(code,idsPerType); + } + void translate(PyObject *vector) throw(INTERP_KERNEL::Exception) { int sz; @@ -530,7 +546,7 @@ namespace ParaMEDMEM { public: void updateTime() const; - void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const throw(INTERP_KERNEL::Exception); void zipCoords() throw(INTERP_KERNEL::Exception); @@ -577,7 +593,7 @@ namespace ParaMEDMEM return res; } - PyObject *getCoords() const throw(INTERP_KERNEL::Exception) + PyObject *getCoords() throw(INTERP_KERNEL::Exception) { DataArrayDouble *ret1=self->getCoords(); ret1->incrRef(); @@ -821,14 +837,14 @@ namespace ParaMEDMEM INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&sz); self->insertNextCell(type,size,tmp); } - DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception) + DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception) { DataArrayInt *ret=self->getNodalConnectivity(); if(ret) ret->incrRef(); return ret; } - DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) + DataArrayInt *getNodalConnectivityIndex() throw(INTERP_KERNEL::Exception) { DataArrayInt *ret=self->getNodalConnectivityIndex(); if(ret) @@ -885,9 +901,9 @@ namespace ParaMEDMEM PyObject *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, PyObject *ids) const throw(INTERP_KERNEL::Exception) { - std::vector idsPerGeoType; - convertPyToNewIntArr3(ids,idsPerGeoType); - MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,idsPerGeoType); + int size; + INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(ids,&size); + MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,tmp,tmp+size); return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ); } @@ -1144,16 +1160,16 @@ namespace ParaMEDMEM { public: static MEDCouplingCMesh *New(); - void setCoords(DataArrayDouble *coordsX, - DataArrayDouble *coordsY=0, - DataArrayDouble *coordsZ=0) throw(INTERP_KERNEL::Exception); - void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); + void setCoords(const DataArrayDouble *coordsX, + const DataArrayDouble *coordsY=0, + const DataArrayDouble *coordsZ=0) throw(INTERP_KERNEL::Exception); + void setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); %extend { std::string __str__() const { return self->simpleRepr(); } - DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) + DataArrayDouble *getCoordsAt(int i) throw(INTERP_KERNEL::Exception) { DataArrayDouble *ret=self->getCoordsAt(i); if(ret) @@ -1495,6 +1511,84 @@ namespace ParaMEDMEM convertPyObjToVecDataArrayDblCst(li,tmp); return DataArrayDouble::Meld(tmp); } + + DataArrayDouble *__getitem__(PyObject *ob) throw(INTERP_KERNEL::Exception) + { + self->checkAllocated(); + int nbOfTuples=self->getNumberOfTuples(); + bool isTuple=PyTuple_Check(ob); + PyObject *obj=0; + if(!isTuple) + obj=ob; + else + { + int sz=PyTuple_Size(ob); + if(sz!=2) + throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); + obj=PyTuple_GetItem(ob,0); + } + MEDCouplingAutoRefCountObjectPtr ret; + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + ret=self->selectByTupleIdSafe(&val,&val+1); + } + else + { + if(!PySlice_Check(obj)) + { + std::ostringstream oss; + oss << "Expecting a slice or an integer for subscriptable object DataArrayDouble on tuples !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + Py_ssize_t strt,stp,step; + PySliceObject *oC=reinterpret_cast(obj); + if(PySlice_GetIndices(oC,nbOfTuples,&strt,&stp,&step)!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArrayDouble invalid : number of tuples is : " << nbOfTuples << " : check with your 1st slice !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret=self->selectByTupleId2(strt,stp,step); + } + } + if(!isTuple) + { + ret->incrRef(); + return ret; + } + int nbOfComponents=self->getNumberOfComponents(); + PyObject *obj1=PyTuple_GetItem(ob,1); + if(PyInt_Check(obj1)) + { + int val=(int)PyInt_AS_LONG(obj1); + std::vector v(1,val); + return ret->keepSelectedComponents(v); + } + else + { + if(!PySlice_Check(obj1)) + { + std::ostringstream oss; + oss << "Expecting a slice or an integer for subscriptable object DataArrayDouble on components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + Py_ssize_t strt,stp,step; + PySliceObject *oC=reinterpret_cast(obj1); + if(PySlice_GetIndices(oC,nbOfComponents,&strt,&stp,&step)!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArrayDouble invalid : number of components is : " << nbOfComponents << " : check with your 2nd slice !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(step<=0) + throw INTERP_KERNEL::Exception("2nd Slice in subscriptable object DataArrayDouble invalid : should be > 0 !"); + Py_ssize_t newNbOfComp=(stp-strt)/step; + std::vector v(newNbOfComp); + for(int i=0;ikeepSelectedComponents(v); + } + } }; %extend ParaMEDMEM::DataArrayInt @@ -1820,6 +1914,84 @@ namespace ParaMEDMEM PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); return ret; } + + DataArrayInt *__getitem__(PyObject *ob) throw(INTERP_KERNEL::Exception) + { + self->checkAllocated(); + int nbOfTuples=self->getNumberOfTuples(); + bool isTuple=PyTuple_Check(ob); + PyObject *obj=0; + if(!isTuple) + obj=ob; + else + { + int sz=PyTuple_Size(ob); + if(sz!=2) + throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); + obj=PyTuple_GetItem(ob,0); + } + MEDCouplingAutoRefCountObjectPtr ret; + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + ret=self->selectByTupleIdSafe(&val,&val+1); + } + else + { + if(!PySlice_Check(obj)) + { + std::ostringstream oss; + oss << "Expecting a slice or an integer for subscriptable object DataArrayInt on tuples !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + Py_ssize_t strt,stp,step; + PySliceObject *oC=reinterpret_cast(obj); + if(PySlice_GetIndices(oC,nbOfTuples,&strt,&stp,&step)!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArrayInt invalid : number of tuples is : " << nbOfTuples << " : check with your 1st slice !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret=self->selectByTupleId2(strt,stp,step); + } + } + if(!isTuple) + { + ret->incrRef(); + return ret; + } + int nbOfComponents=self->getNumberOfComponents(); + PyObject *obj1=PyTuple_GetItem(ob,1); + if(PyInt_Check(obj1)) + { + int val=(int)PyInt_AS_LONG(obj1); + std::vector v(1,val); + return ret->keepSelectedComponents(v); + } + else + { + if(!PySlice_Check(obj1)) + { + std::ostringstream oss; + oss << "Expecting a slice or an integer for subscriptable object DataArrayInt on components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + Py_ssize_t strt,stp,step; + PySliceObject *oC=reinterpret_cast(obj1); + if(PySlice_GetIndices(oC,nbOfComponents,&strt,&stp,&step)!=0) + { + std::ostringstream oss; oss << "Slice in subscriptable object DataArrayInt invalid : number of components is : " << nbOfComponents << " : check with your 2nd slice !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(step<=0) + throw INTERP_KERNEL::Exception("2nd Slice in subscriptable object DataArrayInt invalid : should be > 0 !"); + Py_ssize_t newNbOfComp=(stp-strt)/step; + std::vector v(newNbOfComp); + for(int i=0;ikeepSelectedComponents(v); + } + } }; namespace ParaMEDMEM @@ -2266,6 +2438,7 @@ namespace ParaMEDMEM { public: static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldTemplate *New(TypeOfField type); std::string simpleRepr() const; std::string advancedRepr() const; %extend diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 03a561c8f..2cf25a4d8 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -5896,6 +5896,116 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(expected1,b.getValues()) pass + def testSwigGetItem1(self): + da=DataArrayInt.New() + da.alloc(16,3) + da.rearrange(1) + da.iota(7) + da.rearrange(3) + da.setInfoOnComponent(0,"X [m]") + da.setInfoOnComponent(1,"Y [m]") + da.setInfoOnComponent(2,"Z [km]") + da2=da[5:-1] + self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51],da2.getValues()) + da2=da[4] + self.assertEqual([19, 20, 21],da2.getValues()) + try: + da2=da[4:17] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:-2,2] + self.assertEqual([24, 27, 30, 33, 36, 39, 42, 45, 48],da2.getValues()) + da2=da[5:8,:] + self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30],da2.getValues()) + da2=da[:] + self.assertTrue(da2.isEqual(da)) + da2=da[:,:] + self.assertTrue(da2.isEqual(da)) + try: + da2=da[:,:,:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + try: + da2=da[5:8,-2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:8,:-2] + self.assertEqual([22, 25, 28],da2.getValues()) + try: + da2=da[5:-18,2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:5,2] + self.assertEqual([],da2.getValues()) + pass + + def testSwigGetItem2(self): + da=DataArrayDouble.New() + da.alloc(16,3) + da.rearrange(1) + da.iota(7) + da.rearrange(3) + da.setInfoOnComponent(0,"X [m]") + da.setInfoOnComponent(1,"Y [m]") + da.setInfoOnComponent(2,"Z [km]") + da2=da[5:-1] + self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.],da2.getValues()) + da2=da[4] + self.assertEqual([19., 20., 21],da2.getValues()) + try: + da2=da[4:17] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:-2,2] + self.assertEqual([24., 27., 30., 33., 36., 39., 42., 45., 48.],da2.getValues()) + da2=da[5:8,:] + self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30.],da2.getValues()) + da2=da[:] + self.assertTrue(da2.isEqual(da,1e-12)) + da2=da[:,:] + self.assertTrue(da2.isEqual(da,1e-12)) + try: + da2=da[:,:,:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + try: + da2=da[5:8,-2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:8,:-2] + self.assertEqual([22., 25., 28.],da2.getValues()) + try: + da2=da[5:-18,2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:5,2] + self.assertEqual([],da2.getValues()) + pass + def testDAIAggregateMulti1(self): a=DataArrayInt.New() a.setValues(range(4),2,2) @@ -6481,6 +6591,58 @@ class MEDCouplingBasicsTest(unittest.TestCase): # pass + def testP2Localization1(self): + m=MEDCouplingUMesh.New("testP2",2); + coords=[0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4] + conn=[0,1,2,3,4,5] + coo=DataArrayDouble.New(); + coo.setValues(coords,6,2); + m.setCoords(coo); + m.allocateCells(1); + m.insertNextCell(NORM_TRI6,6,conn[0:6]) + m.finishInsertingCells(); + # + f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f.setMesh(m); + da=DataArrayDouble.New(); + vals1=[1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4] + da.setValues(vals1,6,3); + f.setArray(da); + # + loc=[2.27,1.3] + locs=f.getValueOnMulti(loc); + expected1=[6.0921164547752236, 7.1921164547752232, 8.2921164547752255] + for i in xrange(3): + self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); + pass + pass + + def testP2Localization2(self): + m=MEDCouplingUMesh.New("testP2_2",3); + coords=[0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891] + conn=[0,1,2,3,4,5,6,7,8,9] + coo=DataArrayDouble.New(); + coo.setValues(coords,10,3); + m.setCoords(coo); + m.allocateCells(1); + m.insertNextCell(NORM_TETRA10,10,conn[0:10]) + m.finishInsertingCells(); + # + f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f.setMesh(m); + da=DataArrayDouble.New(); + vals1=[1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2] + da.setValues(vals1,10,1); + f.setArray(da); + # + loc=[0.64637931739890486, -0.16185896817550552, 0.22678966365273748] + locs=f.getValueOnMulti(loc); + expected1=[10.0844021968047] + for i in xrange(1): + self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); + pass + pass + def testGetValueOn2(self): m=MEDCouplingDataForTest.build2DTargetMesh_1(); f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); @@ -6604,6 +6766,86 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(13,mesh.getMeshLength()); # pass + + def testDADCheckIsMonotonic(self): + da=DataArrayDouble.New(); + da.setValues([-1.,1.01,2.03,6.],2,2); + self.assertRaises(InterpKernelException,da.isMonotonic,1e-12); + da.rearrange(1); + self.assertTrue(da.isMonotonic(1e-12)); + da.checkMonotonic(1e-12); + da.setIJ(2,0,6.1); + self.assertTrue(not da.isMonotonic(1e-12)); + self.assertRaises(InterpKernelException,da.checkMonotonic,1e-12); + da.setIJ(2,0,5.99); + self.assertTrue(da.isMonotonic(1e-12)); + self.assertTrue(not da.isMonotonic(1e-1)); + pass + + def testCheckCoherencyDeeper1(self): + m=MEDCouplingDataForTest.build3DSourceMesh_1(); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(8,0,-1); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,-6); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,9);#9>=NbOfNodes + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,8);#OK + m.checkCoherency(); + m.checkCoherency1(); + elts=[1,5] + m.convertToPolyTypes(elts); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(2,0,9);#9>=NbOfNodes + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(2,0,-3); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(2,0,-1); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw because cell#0 is not a polyhedron + m.getNodalConnectivity().setIJ(2,0,4); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(7,0,-1); + m.checkCoherency(); + m.checkCoherency1();#OK because we are in polyhedron connec + m.getNodalConnectivity().setIJ(36,0,14); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. + pass + + def testUnPolyze2(self): + m=MEDCouplingUMesh.New("jjj",3); + coo=DataArrayDouble.New(); + coo.alloc(4,3); + coo.rearrange(1); + coo.iota(0); + coo.rearrange(3); + m.setCoords(coo); + m.allocateCells(2); + m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); + m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); + m.finishInsertingCells(); + m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(4*[m]); + m2.convertToPolyTypes([2]); + m2.unPolyze(); + self.assertEqual(NORM_TETRA4,m2.getTypeOfCell(2)); + self.assertEqual(40,m2.getMeshLength()); + temp2=m2.getNodeIdsOfCell(2); + self.assertEqual(temp2,[0,1,2,3]); + m2.checkCoherency1(); + m3=m2.deepCpy(); + m2.unPolyze(); + self.assertTrue(m3.isEqual(m2,1e-12)); + pass def setUp(self): pass diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py index 9607373a9..421222d63 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -37,6 +37,7 @@ class MEDCouplingDataForTest: myCoords.setValues(targetCoords,9,2); targetMesh.setCoords(myCoords); return targetMesh; + def build2DSourceMesh_1(cls): sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] sourceConn=[0,3,1,0,2,3] @@ -68,6 +69,32 @@ class MEDCouplingDataForTest: targetMesh.setCoords(myCoords); return targetMesh + def build3DSourceMesh_1(self): + sourceCoords=[ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, + 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0] + sourceConn=[8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2] + sourceMesh=MEDCouplingUMesh.New(); + sourceMesh.setMeshDimension(3); + sourceMesh.allocateCells(12); + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[0:4]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[4:8]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[8:12]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[12:16]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[16:20]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[20:24]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[24:28]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[28:32]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[32:36]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[36:40]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[40:44]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[44:48]) + sourceMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(sourceCoords,9,3); + sourceMesh.setCoords(myCoords); + return sourceMesh; + + def build3DSurfTargetMesh_1(self): targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] @@ -511,6 +538,7 @@ class MEDCouplingDataForTest: build2DTargetMesh_1=classmethod(build2DTargetMesh_1) build2DSourceMesh_1=classmethod(build2DSourceMesh_1) build3DTargetMesh_1=classmethod(build3DTargetMesh_1) + build3DSourceMesh_1=classmethod(build3DSourceMesh_1) build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1) build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1) buildCU1DMesh_U=classmethod(buildCU1DMesh_U) diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py index 4f38166b5..df7f5c5ca 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py @@ -48,6 +48,38 @@ class MEDCouplingBasicsTest(unittest.TestCase): pass self.failUnless(1==trgfield.getArray().getNumberOfComponents()); pass + + def testPrepareEx1(self): + sourceMesh=self.build2DSourceMesh_1(); + targetMesh=self.build2DTargetMesh_3(); + # + remapper=MEDCouplingRemapper(); + remapper.setPrecision(1e-12); + remapper.setIntersectionType(Triangulation); + srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); + trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); + srcFt.setMesh(sourceMesh); + trgFt.setMesh(targetMesh); + self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); + srcField=MEDCouplingFieldDouble.New(ON_CELLS); + srcField.setNature(ConservativeVolumic); + srcField.setMesh(sourceMesh); + array=DataArrayDouble.New(); + ptr=sourceMesh.getNumberOfCells()*[None] + for i in xrange(sourceMesh.getNumberOfCells()): + ptr[i]=float(i+7); + pass + array.setValues(ptr,sourceMesh.getNumberOfCells(),1); + srcField.setArray(array); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield.getArray().getValues(); + valuesExpected=[7.75, 7.0625, 4.220173,8.0] + self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); + self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); + for i0 in xrange(4): + self.assertAlmostEqual(valuesExpected[i0],values[i0],12); + pass + pass def build2DSourceMesh_1(self): sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] @@ -78,6 +110,22 @@ class MEDCouplingBasicsTest(unittest.TestCase): myCoords.setValues(targetCoords,9,2); targetMesh.setCoords(myCoords); return targetMesh; + + def build2DTargetMesh_3(self): + targetCoords=[-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, -0.6,1.1, -0.1,1.1] + targetConn=[0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(4); + for i in xrange(4): + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[4*i:4*(i+1)]) + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,10,2); + targetMesh.setCoords(myCoords); + return targetMesh; + pass def setUp(self): pass diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index 19fe8fdae..bb21c4a40 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -18,6 +18,7 @@ // #include "MEDFileField.hxx" +#include "MEDFileMesh.hxx" #include "MEDLoaderBase.hxx" #include "MEDFileUtilities.hxx" @@ -25,10 +26,10 @@ #include -extern med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2]; -extern med_geometrie_element typmainoeud[1]; -extern med_geometrie_element typmai3[32]; +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmainoeud[1]; +extern med_geometry_type typmai3[32]; using namespace ParaMEDMEM; @@ -40,8 +41,8 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFil MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, med_idt fid) throw(INTERP_KERNEL::Exception) try:_father(fath) { - INTERP_KERNEL::AutoPtr locname=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - INTERP_KERNEL::AutoPtr pflname=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + INTERP_KERNEL::AutoPtr locname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr pflname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); std::string fieldName=getName(); std::string meshName=getMeshName(); int iteration=getIteration(); @@ -49,16 +50,15 @@ try:_father(fath) const std::vector& infos=getInfos(); TypeOfField type=getType(); INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); - int nval=MEDnVal(fid,(char *)fieldName.c_str(),type==ON_CELLS?MED_MAILLE:MED_NOEUD,type==ON_CELLS?typmai3[(int)geoType]:MED_NONE, - iteration,order,(char *)meshName.c_str(),MED_COMPACT); + int profilesize,nbi; + int nval=MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,type==ON_CELLS?MED_CELL:MED_NODE,type==ON_CELLS?typmai3[(int)geoType]:MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi);//to generalize _arr=DataArrayDouble::New(); _arr->alloc(nval,infos.size()); - MEDchampLire(fid,(char *)getMeshName().c_str(),(char *)fieldName.c_str(),(unsigned char*)_arr->getPointer(),MED_FULL_INTERLACE,MED_ALL,locname, - pflname,MED_COMPACT,type==ON_CELLS?MED_MAILLE:MED_NOEUD, - type==ON_CELLS?typmai3[(int)geoType]:MED_NONE, - iteration,order); - _profile=pflname; - _localization=locname; + MEDfieldValueWithProfileRd(fid,fieldName.c_str(),iteration,order,type==ON_CELLS?MED_CELL:MED_NODE,type==ON_CELLS?typmai3[(int)geoType]:MED_NONE,MED_COMPACT_PFLMODE, + pflname,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,reinterpret_cast(_arr->getPointer())); + _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE); + _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE); } catch(INTERP_KERNEL::Exception& e) { @@ -105,6 +105,11 @@ int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfComponents() const return _father->getNumberOfComponents(); } +int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const +{ + return _arr->getNumberOfTuples(); +} + const std::vector& MEDFileFieldPerMeshPerTypePerDisc::getInfos() const { return _father->getInfos(); @@ -195,6 +200,28 @@ std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsed() const return ret; } +bool MEDFileFieldPerMeshPerType::isOnNode(int& type, int& number, const DataArrayInt* &arrs) const throw(INTERP_KERNEL::Exception) +{ + if(_type!=ON_NODES) + return false; + type=INTERP_KERNEL::NORM_ERROR; + number=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + number+=(*it)->getNumberOfTuples(); + return true; +} + +bool MEDFileFieldPerMeshPerType::isOnCell(int dimDimReq, int& type, int& number, const DataArrayInt* &arrs) const throw(INTERP_KERNEL::Exception) +{ + if(_type!=ON_CELLS) + return false; + type=(int)_geo_type; + number=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + number+=(*it)->getNumberOfTuples(); + return true; +} + MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception):_father(fath),_type(type),_geo_type(geoType) { } @@ -206,9 +233,9 @@ void MEDFileFieldPerMeshPerType::finishLoading(med_idt fid) throw(INTERP_KERNEL: _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,fid); } -MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileField1TSWithoutDAS *fath, const char *meshName, double time) +MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileField1TSWithoutDAS *fath, double time) { - return new MEDFileFieldPerMesh(fath,meshName,time); + return new MEDFileFieldPerMesh(fath,time); } void MEDFileFieldPerMesh::pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) @@ -250,7 +277,7 @@ std::string MEDFileFieldPerMesh::getName() const std::string MEDFileFieldPerMesh::getMeshName() const { - return _mesh_name; + return _father->getMeshName(); } int MEDFileFieldPerMesh::getNumberOfComponents() const @@ -297,7 +324,55 @@ std::vector MEDFileFieldPerMesh::getLocsReallyUsed() const return ret; } -MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileField1TSWithoutDAS *fath, const char *meshName, double time):_father(fath),_mesh_name(meshName),_time(time) +MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) +{ + std::vector arrs; + std::vector distrib=getDistributionOfTypes(meshDimRelToMaxExt,mesh->getMeshDimension(),arrs); + MEDCouplingAutoRefCountObjectPtr da=mesh->checkTypeConsistencyAndContig(distrib,arrs); + return 0; +} + +std::vector MEDFileFieldPerMesh::getDistributionOfTypes(int meshDimRelToMaxExt, int mdim, std::vector& arrs) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("Invalid meshDimRelToMaxExt parameter passed ! must be 1 for node and 0,-1,-2,-3 for cells !"); + std::vector ret; + int tmp2,tmp3; + arrs.clear(); + const DataArrayInt *arrTmp=0; + if(meshDimRelToMaxExt==1) + {//On node + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + if((*it)->isOnNode(tmp2,tmp3,arrTmp)) + { + ret.push_back(-1); + ret.push_back(tmp2); + ret.push_back(tmp3); + if(arrTmp) + arrs.push_back(arrTmp); + } + if(ret.size()>2) + throw INTERP_KERNEL::Exception("Detected on same time step two different discretization ... Should never happen !"); + } + else + { + int dimTarget=mdim+meshDimRelToMaxExt; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + if((*it)->isOnCell(dimTarget,tmp2,tmp3,arrTmp)) + { + ret.push_back((int)(*it)->getGeoType()); + ret.push_back(tmp2); + ret.push_back(tmp3); + if(arrTmp) + arrs.push_back(arrTmp); + } + } + if(ret.empty()) + throw INTERP_KERNEL::Exception("No field part correspond to requested meshdimRel !"); + return ret; +} + +MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileField1TSWithoutDAS *fath, double time):_father(fath),_time(time) { } @@ -305,17 +380,27 @@ void MEDFieldFieldGlobs::loadProfileInFile(med_idt fid, int id, const char *pflN { _pfls[id]=DataArrayInt::New(); _pfls[id]->alloc(lgth,1); - MEDprofilLire(fid,_pfls[id]->getPointer(),(char *)pflName); + MEDprofileRd(fid,pflName,_pfls[id]->getPointer()); + _pfls[id]->applyLin(1,-1,0);//Converting into C format } void MEDFieldFieldGlobs::loadProfileInFile(med_idt fid, int i) { - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); int sz; - MEDprofilInfo(fid,i,pflName,&sz); + MEDprofileInfo(fid,i,pflName,&sz); _pfls[i]=DataArrayInt::New(); _pfls[i]->alloc(sz,1); - MEDprofilLire(fid,_pfls[i]->getPointer(),(char *)pflName); + MEDprofileRd(fid,pflName,_pfls[i]->getPointer()); +} + +MEDFieldFieldGlobs::MEDFieldFieldGlobs(const char *fname):_file_name(fname) +{ +} + +void MEDFieldFieldGlobs::setFileName(const char *fileName) +{ + _file_name=fileName; } std::vector MEDFieldFieldGlobs::getPfls() const @@ -336,41 +421,34 @@ std::vector MEDFieldFieldGlobs::getLocs() const return ret; } -MEDFileField1TSWithoutDAS *MEDFileField1TSWithoutDAS::New(const char *fieldName, int iteration, int order, const std::vector& infos) +MEDFileField1TSWithoutDAS *MEDFileField1TSWithoutDAS::New(const char *fieldName, const char *meshName, int iteration, int order, int meshIt, int meshOrder, const std::vector& infos) { - return new MEDFileField1TSWithoutDAS(fieldName,iteration,order,infos); + return new MEDFileField1TSWithoutDAS(fieldName,meshName,iteration,order,meshIt,meshOrder,infos); } -void MEDFileField1TSWithoutDAS::pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, double time, const char *meshName) const +void MEDFileField1TSWithoutDAS::pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, double time) const { _types.push_back(type); _geo_types.push_back(geoType); _times.push_back(time); - _meshes.push_back(meshName); } void MEDFileField1TSWithoutDAS::finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception) { - std::vector meshesOnlyOnce; - int nbOfTurn=_meshes.size(); - for(int i=0;i::iterator it=std::find(meshesOnlyOnce.begin(),meshesOnlyOnce.end(),_meshes[i]); - if(it==meshesOnlyOnce.end()) - { - _field_per_mesh.push_back(MEDFileFieldPerMesh::New(this,_meshes[i].c_str(),_times[i])); - meshesOnlyOnce.push_back(_meshes[i]); - _field_per_mesh.back()->pushBack(_types[i],_geo_types[i]); - } - else - { - int w=std::distance(meshesOnlyOnce.begin(),it); - _field_per_mesh[w]->pushBack(_types[i],_geo_types[i]); - } - } - int nbOfMeshes=_field_per_mesh.size(); - for(int i=0;ifinishLoading(fid); + _field_per_mesh.push_back(MEDFileFieldPerMesh::New(this,_times[0])); + _field_per_mesh[0]->finishLoading(fid); +} + +MEDCouplingFieldDouble *MEDFileField1TSWithoutDAS::getFieldAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(glob->getFileName(),_mesh_name.c_str(),_mesh_iteration,_mesh_order); + MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMaxExt); + return _field_per_mesh[0]->getFieldOnMeshAtLevel(meshDimRelToMaxExt,glob,m); +} + +MEDCouplingFieldDouble *MEDFileField1TSWithoutDAS::getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) +{ + return _field_per_mesh[0]->getFieldOnMeshAtLevel(meshDimRelToMaxExt,glob,mesh); } std::vector MEDFileField1TSWithoutDAS::getPflsReallyUsed() const @@ -407,7 +485,9 @@ std::vector MEDFileField1TSWithoutDAS::getLocsReallyUsed() const return ret; } -MEDFileField1TSWithoutDAS::MEDFileField1TSWithoutDAS(const char *fieldName, int iteration, int order, const std::vector& infos):_name(fieldName),_infos(infos),_iteration(iteration),_order(order) +MEDFileField1TSWithoutDAS::MEDFileField1TSWithoutDAS(const char *fieldName, const char *meshName, int iteration, int order, int meshIt, int meshOrder, + const std::vector& infos):_name(fieldName),_mesh_name(meshName),_infos(infos),_iteration(iteration),_order(order), + _mesh_iteration(meshIt),_mesh_order(meshOrder) { } @@ -417,29 +497,35 @@ MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldNam } MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) -try:MEDFileField1TSWithoutDAS(fieldName,iteration,order,std::vector()) +try:MEDFileField1TSWithoutDAS(fieldName,"",iteration,order,-1,-1,std::vector()),MEDFieldFieldGlobs(fileName) { MEDFileUtilities::CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - int nbFields=MEDnChamp(fid,0); - med_type_champ typcha; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int nbFields=MEDnField(fid); + med_field_type typcha; bool found=false; std::vector fns(nbFields); for(int i=0;i comp=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); + int ncomp=MEDfieldnComponent(fid,i+1); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localMesh; + int nbOfStep; + MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); std::string tmp(nomcha); fns[i]=tmp; found=(tmp==fieldName); if(found) { + std::string mname=MEDLoaderBase::buildStringFromFortran(nomMaa,MED_NAME_SIZE); + _mesh_name=mname; _infos.resize(ncomp); for(int j=0;j _pfls.resize(sz); for(int i=0;i& infos) throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + return MEDFileField1TSWithoutDAS::getFieldAtLevel(meshDimRelToMaxExt,this); +} + +MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) +{ + return MEDFileField1TSWithoutDAS::getFieldOnMeshAtLevel(meshDimRelToMaxExt,this,mesh); +} + +MEDFileFieldMultiTSWithoutDAS *MEDFileFieldMultiTSWithoutDAS::New(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) { - return new MEDFileFieldMultiTSWithoutDAS(fid,fieldName,id,infos); + return new MEDFileFieldMultiTSWithoutDAS(fid,fieldName,id,infos,nbOfStep); } MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS(const char *fieldName):_name(fieldName) { } -MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos) throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTSWithoutDAS::MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) try:_name(fieldName),_infos(infos) { - finishLoading(fid); + finishLoading(fid,nbOfStep); } catch(INTERP_KERNEL::Exception& e) { throw e; } -void MEDFileFieldMultiTSWithoutDAS::finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception) +void MEDFileFieldMultiTSWithoutDAS::finishLoading(med_idt fid, int nbPdt) throw(INTERP_KERNEL::Exception) { - for(int i=0;ifinishLoading(fid); } -void MEDFileFieldMultiTSWithoutDAS::appendTimeStepEntry(med_idt fid, med_entite_maillage entity, int i, int j) throw(INTERP_KERNEL::Exception) +void MEDFileFieldMultiTSWithoutDAS::appendTimeStepEntry(med_idt fid, med_entity_type entity, int i, int j) throw(INTERP_KERNEL::Exception) { std::vector< std::pair > ts; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_int numdt=0,numo=0; + med_int meshIt=0,meshOrder=0; med_float dt=0.0; - med_booleen local; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - MEDpasdetempsInfo(fid,(char *)_name.c_str(),MED_MAILLE,typmai[i],j+1,&ngauss,&numdt,&numo,dt_unit,&dt,maa_ass,&local,&nbrefmaa); + MEDfieldComputingStepMeshInfo(fid,_name.c_str(),j+1,&numdt,&numo,&dt,&meshIt,&meshOrder); std::pair p(numdt,numo); std::vector< std::pair >::iterator where=std::find(ts.begin(),ts.end(),p); if(where==ts.end()) { ts.push_back(p); - _time_steps.push_back(MEDFileField1TSWithoutDAS::New(_name.c_str(),numdt,numo,_infos)); - _time_steps.back()->pushBack(entity==MED_MAILLE?ON_CELLS:ON_NODES,entity==MED_MAILLE?typmai2[i]:INTERP_KERNEL::NORM_ERROR,dt,maa_ass); + _time_steps.push_back(MEDFileField1TSWithoutDAS::New(_name.c_str(),_mesh_name.c_str(),numdt,numo,meshIt,meshOrder,_infos)); + _time_steps.back()->pushBack(entity==MED_CELL?ON_CELLS:ON_NODES,entity==MED_CELL?typmai2[i]:INTERP_KERNEL::NORM_ERROR,dt); } else { int w=std::distance(ts.begin(),where); - _time_steps[w]->pushBack(entity==MED_MAILLE?ON_CELLS:ON_NODES,entity==MED_MAILLE?typmai2[i]:INTERP_KERNEL::NORM_ERROR,dt,maa_ass); + _time_steps[w]->pushBack(entity==MED_CELL?ON_CELLS:ON_NODES,entity==MED_CELL?typmai2[i]:INTERP_KERNEL::NORM_ERROR,dt); } } @@ -556,35 +644,46 @@ std::vector MEDFileFieldMultiTSWithoutDAS::getLocsReallyUsed() cons return ret; } +int MEDFileFieldMultiTSWithoutDAS::getNumberOfTS() const +{ + return _time_steps.size(); +} + MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) { return new MEDFileFieldMultiTS(fileName,fieldName); } MEDFileFieldMultiTS::MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldMultiTSWithoutDAS(fieldName) +try:MEDFileFieldMultiTSWithoutDAS(fieldName),MEDFieldFieldGlobs(fileName) { MEDFileUtilities::CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - int nbFields=MEDnChamp(fid,0); - med_type_champ typcha; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int nbFields=MEDnField(fid); + med_field_type typcha; bool found=false; std::vector fns(nbFields); + int nbstep2=-1; for(int i=0;i comp=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); + int ncomp=MEDfieldnComponent(fid,i+1); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localMesh; + int nbOfStep; + MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); std::string tmp(nomcha); fns[i]=tmp; found=(tmp==fieldName); if(found) { + nbstep2=nbOfStep; _infos.resize(ncomp); for(int j=0;j(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - finishLoading(fid); - MEDfermer(fid); + finishLoading(fid,nbstep2); } catch(INTERP_KERNEL::Exception& e) { @@ -612,30 +710,33 @@ int MEDFileFields::getNumberOfFields() const } MEDFileFields::MEDFileFields(const char *fileName) throw(INTERP_KERNEL::Exception) -try +try:MEDFieldFieldGlobs(fileName) { MEDFileUtilities::CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - int nbFields=MEDnChamp(fid,0); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int nbFields=MEDnField(fid); _fields.resize(nbFields); - med_type_champ typcha; + med_field_type typcha; for(int i=0;i comp=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_TAILLE_PNOM+1]; - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); + int ncomp=MEDfieldnComponent(fid,i+1); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localMesh; + int nbOfStep; + MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); std::vector infos(ncomp); for(int j=0;j& getInfos() const; std::string getProfile() const; std::string getLocalization() const; private: MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, med_idt fid) throw(INTERP_KERNEL::Exception); + private: MEDFileFieldPerMeshPerType *_father; MEDCouplingAutoRefCountObjectPtr< DataArrayDouble > _arr; @@ -97,6 +103,8 @@ namespace ParaMEDMEM const std::vector& getInfos() const; std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; + bool isOnNode(int& type, int& number, const DataArrayInt* &arrs) const throw(INTERP_KERNEL::Exception); + bool isOnCell(int dimDimReq, int& type, int& number, const DataArrayInt* &arrs) const throw(INTERP_KERNEL::Exception); private: MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception); private: @@ -109,7 +117,7 @@ namespace ParaMEDMEM class MEDFileFieldPerMesh : public RefCountObject { public: - static MEDFileFieldPerMesh *New(MEDFileField1TSWithoutDAS *fath, const char *meshName, double time); + static MEDFileFieldPerMesh *New(MEDFileField1TSWithoutDAS *fath, double time); void pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType); void finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception); double getTime() const; @@ -121,12 +129,13 @@ namespace ParaMEDMEM const std::vector& getInfos() const; std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; + std::vector getDistributionOfTypes(int meshDimRelToMaxExt, int mdim, std::vector& arrs) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); private: - MEDFileFieldPerMesh(MEDFileField1TSWithoutDAS *fath, const char *meshName, double time); + MEDFileFieldPerMesh(MEDFileField1TSWithoutDAS *fath, double time); private: MEDFileField1TSWithoutDAS *_father; std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > _field_pm_pt; - std::string _mesh_name; double _time; private: mutable std::vector _types; @@ -136,41 +145,53 @@ namespace ParaMEDMEM class MEDFieldFieldGlobs { public: + MEDFieldFieldGlobs(const char *fname); void loadProfileInFile(med_idt fid, int id, const char *pflName, int lgth) throw(INTERP_KERNEL::Exception); void loadProfileInFile(med_idt fid, int id); std::vector getPfls() const; std::vector getLocs() const; + void setFileName(const char *fileName); + const char *getFileName() const { return _file_name.c_str(); } protected: std::vector< MEDCouplingAutoRefCountObjectPtr > _pfls; std::vector< MEDCouplingAutoRefCountObjectPtr > _locs; + std::string _file_name; }; class MEDFileField1TSWithoutDAS : public RefCountObject { public: - static MEDFileField1TSWithoutDAS *New(const char *fieldName, int iteration, int order, const std::vector& infos); - void pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, double time, const char *meshName) const; - void finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception); int getIteration() const { return _iteration; } int getOrder() const { return _order; } std::string getName() const { return _name; } + std::string getMeshName() const { return _mesh_name; } int getNumberOfComponents() const { return _infos.size(); } const std::vector& getInfos() const { return _infos; } std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; + // + static MEDFileField1TSWithoutDAS *New(const char *fieldName, const char *meshName, int iteration, int order, int meshIt, int meshOrder, const std::vector& infos); + void pushBack(TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, double time) const; + void finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception); + protected: + MEDCouplingFieldDouble *getFieldAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDFieldFieldGlobs *glob, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); protected: - MEDFileField1TSWithoutDAS(const char *fieldName, int iteration, int order, const std::vector& infos); + MEDFileField1TSWithoutDAS(const char *fieldName, const char *meshName, int iteration, int order, int meshIt, int meshOrder, + const std::vector& infos); protected: std::string _name; + std::string _mesh_name; std::vector _infos; std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > > _field_per_mesh; int _iteration; int _order; + int _mesh_iteration; + int _mesh_order; private: mutable std::vector _types; mutable std::vector _geo_types; mutable std::vector _times; - mutable std::vector _meshes; }; /*! @@ -180,6 +201,9 @@ namespace ParaMEDMEM { public: static MEDFileField1TS *New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setFileName(const char *fileName); + MEDCouplingFieldDouble *getFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(int meshDimRelToMaxExt, const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); private: MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); }; @@ -187,16 +211,18 @@ namespace ParaMEDMEM class MEDFileFieldMultiTSWithoutDAS : public RefCountObject { public: - static MEDFileFieldMultiTSWithoutDAS *New(med_idt fid, const char *fieldName, int id, const std::vector& infos) throw(INTERP_KERNEL::Exception); + static MEDFileFieldMultiTSWithoutDAS *New(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); + int getNumberOfTS() const; protected: MEDFileFieldMultiTSWithoutDAS(const char *fieldName); - MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos) throw(INTERP_KERNEL::Exception); - void finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception); - void appendTimeStepEntry(med_idt fid, med_entite_maillage entity, int i, int j) throw(INTERP_KERNEL::Exception); + MEDFileFieldMultiTSWithoutDAS(med_idt fid, const char *fieldName, int id, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception); + void finishLoading(med_idt fid, int nbPdt) throw(INTERP_KERNEL::Exception); + void appendTimeStepEntry(med_idt fid, med_entity_type entity, int i, int j) throw(INTERP_KERNEL::Exception); std::vector getPflsReallyUsed() const; std::vector getLocsReallyUsed() const; protected: std::string _name; + std::string _mesh_name; std::vector _infos; std::vector< MEDCouplingAutoRefCountObjectPtr > _time_steps; }; @@ -220,8 +246,6 @@ namespace ParaMEDMEM public: static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); int getNumberOfFields() const; - std::vector getPfls() const; - std::vector getLocs() const; private: MEDFileFields(const char *fileName) throw(INTERP_KERNEL::Exception); private: diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 66f27e2e5..6a026ac24 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -27,233 +27,142 @@ #include "InterpKernelAutoPtr.hxx" #include +#include using namespace ParaMEDMEM; -MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} +const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; -MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) +MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_too_long_str(0),_zipconn_pol(2) { - return new MEDFileUMesh(fileName,mName); } -MEDFileUMesh *MEDFileUMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception) +MEDFileMesh *MEDFileMesh::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 << "\" !"; + std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - return new MEDFileUMesh(fileName,ms.front().c_str()); -} - -MEDFileUMesh *MEDFileUMesh::New() -{ - return new MEDFileUMesh; -} - -MEDFileUMesh::MEDFileUMesh():_too_long_str(0),_zipconn_pol(2) -{ -} - -MEDFileUMesh::MEDFileUMesh(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception) - try:_too_long_str(0) - { - MEDFileUtilities::CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - MEDFileUMeshL2 loaderl2; - loaderl2.loadAll(fid,MEDFileUMeshL2::getMeshIdFromName(fid,mName),mName); - int lev=loaderl2.getNumberOfLevels(); - _ms.resize(lev); - for(int i=0;i(this))->addFamily(0,"FAMILLE_ZERO"); - med_mode_acces medmod=MEDFileUtilities::TraduceWriteMode(mode); - med_idt fid=MEDouvrir((char *)fileName,medmod); - std::ostringstream oss; oss << "MEDFileUMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); - const DataArrayDouble *coo=_coords; - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_TAILLE_NOM,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_TAILLE_DESC,desc,_too_long_str); - int spaceDim=coo?coo->getNumberOfComponents():0; - int mdim=getMeshDimension(); - MEDmaaCr(fid,maa,spaceDim,MED_NON_STRUCTURE,desc);//spaceDim is false but to make reader happy for 3DSurf and 2DCurve meshes ! - MEDdimEspaceCr(fid,maa,spaceDim); - MEDFileUMeshL2::writeCoords(fid,maa,_coords,_fam_coords,_num_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->write(fid,maa,mdim); - MEDFileUMeshL2::writeFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); - MEDfermer(fid); -} - -std::vector MEDFileUMesh::getNonEmptyLevels() const -{ - std::vector ret; - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - if(!(*it)->empty()) - ret.push_back(lev); - return ret; -} - -std::vector MEDFileUMesh::getNonEmptyLevelsExt() const -{ - std::vector ret0=getNonEmptyLevels(); - if((const DataArrayDouble *) _coords) + MEDFileUtilities::CheckFileForRead(fileName); + ParaMEDMEM::MEDCouplingMeshType meshType; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int dt,it; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2); + switch(meshType) { - std::vector ret(ret0.size()+1); - ret[0]=1; - std::copy(ret0.begin(),ret0.end(),ret.begin()+1); - return ret; + case UNSTRUCTURED: + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); + ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it); + ret->incrRef(); + return (MEDFileUMesh *)ret; + } + case CARTESIAN: + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); + ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it); + ret->incrRef(); + return (MEDFileCMesh *)ret; + } + default: + { + std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } - return ret0; } -int MEDFileUMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception) +MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) { - std::string oname(name); - std::map::const_iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) + MEDFileUtilities::CheckFileForRead(fileName); + ParaMEDMEM::MEDCouplingMeshType meshType; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + int dummy0,dummy1; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + switch(meshType) { - std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + case UNSTRUCTURED: + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); + ret->loadUMeshFromFile(fid,mName,dt,it); + ret->incrRef(); + return (MEDFileUMesh *)ret; + } + case CARTESIAN: + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); + ret->loadCMeshFromFile(fid,mName,dt,it); + ret->incrRef(); + return (MEDFileCMesh *)ret; + } + default: + { + std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } - return (*it).second; } -int MEDFileUMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception) +bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const { - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + if(_order!=other->_order) { - ret=std::max((*it).second,ret); + what="Orders differ !"; + return false; } - return ret; -} - -std::vector MEDFileUMesh::getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception) -{ - std::vector famIds; - for(std::vector::const_iterator it=famNames.begin();it!=famNames.end();it++) + if(_iteration!=other->_iteration) { - std::map::const_iterator it2=_families.find(*it); - if(it2==_families.end()) - { - std::ostringstream oss; oss << "No such family in mesh \"" << _name << "\" : " << *it; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - famIds.push_back((*it2).second); + what="Iterations differ !"; + return false; } - return famIds; -} - -std::string MEDFileUMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception) -{ - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second==id) - return (*it).first; - std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileUMesh::getMeshDimension() const -{ - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - return (*it)->getMeshDimension()+lev; - throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); -} - -int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) -{ - if(meshDimRelToMaxExt==1) + if(fabs(_time-other->_time)>eps) { - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !"); - return _coords->getNumberOfTuples(); + what="Time values differ !"; + return false; } - return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize(); -} - -const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) -{ - if(meshDimRelToMaxExt==1) + if(_dt_unit!=other->_dt_unit) { - if(!((const DataArrayInt *)_fam_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamilyFieldAtLevel : no coordinates specified !"); - return _fam_coords; + what="Time units differ !"; + return false; } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getFamilyField(); + if(_name!=other->_name) + { + what="Names differ !"; + return false; + } + if(_univ_name!=other->_univ_name) + { + what="Univ names differ !"; + return false; + } + if(_desc_name!=other->_desc_name) + { + what="Description names differ !"; + return false; + } + if(!areGrpsEqual(other,what)) + return false; + if(!areFamsEqual(other,what)) + return false; + return true; } -const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::clearNonDiscrAttributes() const { - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayInt *)_num_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getNumberFieldAtLevel : no coordinates renum specified !"); - return _num_coords; - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getNumberField(); + } -const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other) { - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayInt *)_num_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); - return _rev_num_coords; - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getRevNumberField(); + _groups=other._groups; + _families=other._families; } -std::vector MEDFileUMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception) { std::string oname(name); std::map >::const_iterator it=_groups.find(oname); @@ -267,7 +176,7 @@ std::vector MEDFileUMesh::getFamiliesOnGroup(const char *name) cons return (*it).second; } -std::vector MEDFileUMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception) { std::vector ret; for(std::map >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++) @@ -282,7 +191,7 @@ std::vector MEDFileUMesh::getGroupsOnFamily(const char *name) const return ret; } -std::vector MEDFileUMesh::getGroupsNames() const +std::vector MEDFileMesh::getGroupsNames() const { std::vector ret(_groups.size()); int i=0; @@ -291,7 +200,7 @@ std::vector MEDFileUMesh::getGroupsNames() const return ret; } -std::vector MEDFileUMesh::getFamiliesNames() const +std::vector MEDFileMesh::getFamiliesNames() const { std::vector ret(_families.size()); int i=0; @@ -300,7 +209,7 @@ std::vector MEDFileUMesh::getFamiliesNames() const return ret; } -void MEDFileUMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception) +void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception) { std::string oname(name); std::map >::iterator it=_groups.find(oname); @@ -314,7 +223,7 @@ void MEDFileUMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception) _groups.erase(it); } -void MEDFileUMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception) +void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception) { std::string oname(name); std::map::iterator it=_families.find(oname); @@ -328,7 +237,7 @@ void MEDFileUMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception _families.erase(it); } -void MEDFileUMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception) +void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception) { std::string oname(oldName); std::map >::iterator it=_groups.find(oname); @@ -343,7 +252,7 @@ void MEDFileUMesh::changeGroupName(const char *oldName, const char *newName) thr it=_groups.find(nname); if(it!=_groups.end()) { - std::ostringstream oss; oss << "Such groupname \"" << newName << " already exists ! Kill it before !"; + std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } std::vector cpy=(*it).second; @@ -351,7 +260,7 @@ void MEDFileUMesh::changeGroupName(const char *oldName, const char *newName) thr _groups[newName]=cpy; } -void MEDFileUMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception) +void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception) { std::string oname(oldName); std::map::iterator it=_families.find(oname); @@ -374,145 +283,738 @@ void MEDFileUMesh::changeFamilyName(const char *oldName, const char *newName) th _families[newName]=cpy; } -DataArrayDouble *MEDFileUMesh::getCoords() const +bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const { - MEDCouplingAutoRefCountObjectPtr tmp(_coords); - if((DataArrayDouble *)tmp) + if(_families==other->_families) + return true; + std::map fam0; + std::map fam1; + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + if((*it).second!=0) + fam0[(*it).first]=(*it).second; + for(std::map::const_iterator it=other->_families.begin();it!=other->_families.end();it++) + if((*it).second!=0) + fam1[(*it).first]=(*it).second; + return fam0==fam1; +} + +bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const +{ + if(_groups==other->_groups) + return true; + bool ret=true; + std::size_t sz=_groups.size(); + if(sz!=other->_groups.size()) { - tmp->incrRef(); - return tmp; + what="Groups differ because not same number !\n"; + ret=false; } - return 0; + if(ret) + { + std::map >::const_iterator it1=_groups.begin(); + for(std::size_t i=0;i >::const_iterator it2=other->_groups.find((*it1).first); + if(it2!=other->_groups.end()) + { + std::set s1((*it1).second.begin(),(*it1).second.end()); + std::set s2((*it2).second.begin(),(*it2).second.end()); + ret=(s1==s2); + } + else + { + ret=false; + what="A group in first mesh exists not in other !\n"; + } + } + } + if(!ret) + { + std::ostringstream oss; oss << "Groups description differs :\n"; + oss << "First group description :\n"; + for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + oss << " Group \"" << (*it).first << "\" on following families :\n"; + for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + oss << " \"" << *it2 << "\n"; + } + oss << "Second group description :\n"; + for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) + { + oss << " Group \"" << (*it).first << "\" on following families :\n"; + for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + oss << " \"" << *it2 << "\n"; + } + what+=oss.str(); + } + return ret; } -MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) +bool MEDFileMesh::existsFamily(int famId) const { - std::vector tmp(1); - tmp[0]=grp; - MEDCouplingUMesh *ret=getGroups(meshDimRelToMaxExt,tmp,renum); - ret->setName(grp); - return ret; + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + return true; + return false; } -DataArrayInt *MEDFileUMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) +bool MEDFileMesh::existsFamily(const char *familyName) const { - std::vector tmp(1); - tmp[0]=grp; - DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(grp); - return ret; + std::string fname(familyName); + return _families.find(fname)!=_families.end(); } -MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::setFamilyId(const char *familyName, int id) { - std::set fams; - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) + std::string fname(familyName); + _families[fname]=id; +} + +/*! + * This method appends a new entry in _families attribute. An exception is thrown if either the famId is already + * kept by an another familyName. An exception is thrown if name 'familyName' is alreadyset with a different 'famId'. + */ +void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception) +{ + std::string fname(familyName); + std::map::const_iterator it=_families.find(fname); + if(it==_families.end()) { - std::map >::const_iterator it2=_groups.find(*it); - if(it2==_groups.end()) + for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families[fname]=famId; + } + else + { + if((*it).second!=famId) { - std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - fams.insert((*it2).second.begin(),(*it2).second.end()); } - std::vector fams2(fams.begin(),fams.end()); - return getFamilies(meshDimRelToMaxExt,fams2,renum); } -DataArrayInt *MEDFileUMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::addGrpOnFamily(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception) { - std::set fams; - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) + std::string grpn(grpName); + std::string famn(famName); + if(grpn.empty() || famn.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh::addGrpOnFamily : input strings must be non null !"); + std::map >::iterator it=_groups.find(grpn); + if(it==_groups.end()) { - std::map >::const_iterator it2=_groups.find(*it); - if(it2==_groups.end()) - { - std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - fams.insert((*it2).second.begin(),(*it2).second.end()); + _groups[grpn].push_back(famn); + } + else + { + std::vector::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn); + if(it2==(*it).second.end()) + (*it).second.push_back(famn); } - std::vector fams2(fams.begin(),fams.end()); - return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); } -MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::setFamilyInfo(const std::map& info) { - std::vector tmp(1); - tmp[0]=fam; - MEDCouplingUMesh *ret=getFamilies(meshDimRelToMaxExt,tmp,renum); - ret->setName(fam); - return ret; + _families=info; } -DataArrayInt *MEDFileUMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) +void MEDFileMesh::setGroupInfo(const std::map >&info) { - std::vector tmp(1); - tmp[0]=fam; - DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(fam); - return ret; + _groups=info; } -MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception) { - if(meshDimRelToMaxExt==1) + std::string oname(name); + std::map::const_iterator it=_families.find(oname); + std::vector fams=getFamiliesNames(); + if(it==_families.end()) { - MEDCouplingAutoRefCountObjectPtr arr=getFamiliesArr(1,fams,renum); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); - ret->setCoords(c); - ret->incrRef(); + std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; + std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return (*it).second; +} + +int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception) +{ + if(_families.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getMaxFamilyId : no families set !"); + int ret=-std::numeric_limits::max(); + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + { + ret=std::max((*it).second,ret); + } + return ret; +} + +std::vector MEDFileMesh::getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception) +{ + std::vector famIds; + for(std::vector::const_iterator it=famNames.begin();it!=famNames.end();it++) + { + std::map::const_iterator it2=_families.find(*it); + if(it2==_families.end()) + { + std::ostringstream oss; oss << "No such family in mesh \"" << _name << "\" : " << *it; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + famIds.push_back((*it2).second); + } + return famIds; +} + +std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception) +{ + for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) + if((*it).second==id) + return (*it).first; + std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(1); + tmp[0]=grp; + DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); + ret->setName(grp); + return ret; +} + +DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) +{ + std::set fams; + for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) + { + std::map >::const_iterator it2=_groups.find(*it); + if(it2==_groups.end()) + { + std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + fams.insert((*it2).second.begin(),(*it2).second.end()); + } + std::vector fams2(fams.begin(),fams.end()); + return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); +} + +DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(1); + tmp[0]=fam; + DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); + ret->setName(fam); + return ret; +} + +DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(1); + tmp[0]=grp; + DataArrayInt *ret=getNodeGroupsArr(tmp,renum); + ret->setName(grp); + return ret; +} + +DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) +{ + return getGroupsArr(1,grps,renum); +} + +DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) +{ + std::vector tmp(1); + tmp[0]=fam; + DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); + ret->setName(fam); + return ret; +} + +DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +{ + return getFamiliesArr(1,fams,renum); +} + +void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) throw(INTERP_KERNEL::Exception) +{ + if(grps.empty()) + return ; + std::set grpsName; + std::vector grpsName2(grps.size()); + int i=0; + + for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) + { + grpsName.insert((*it)->getName()); + grpsName2[i]=(*it)->getName(); + } + if(grpsName.size()!=grps.size()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !"); + if(grpsName.find(std::string(""))!=grpsName.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !"); + int sz=getSizeAtLevel(meshDimRelToMaxExt); + MEDCouplingAutoRefCountObjectPtr fam; + std::vector< std::vector > fidsOfGroups; + if(!renum) + { + fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); + } + else + { + std::vector< MEDCouplingAutoRefCountObjectPtr > grps2(grps.size()); + for(unsigned int i=0;isetName(grps[i]->getName().c_str()); + } + std::vector grps3(grps2.begin(),grps2.end()); + fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); + } + int offset=1; + if(!_families.empty()) + offset=getMaxFamilyId()+1; + TranslateFamilyIds(offset,fam,fidsOfGroups); + std::set ids=fam->getDifferentValues(); + appendFamilyEntries(ids,fidsOfGroups,grpsName2); + setFamilyFieldArr(meshDimRelToMaxExt,fam); +} + +/*! + * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids + * not in '_families'. Groups information are given in parameters in order to give to families representative names. + * For the moment, the two last input parameters are not taken into account. + */ +void MEDFileMesh::appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) +{ + std::map famInv; + for(std::set::const_iterator it=famIds.begin();it!=famIds.end();it++) + { + std::ostringstream oss; + oss << "Family_" << (*it); + _families[oss.str()]=(*it); + famInv[*it]=oss.str(); + } + int i=0; + for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) + { + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + { + _groups[grpNames[i]].push_back(famInv[*it2]); + } + } +} + +void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) +{ + famArr->applyLin(1,offset,0); + for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) + std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus(),offset)); +} + +MEDFileUMesh *MEDFileUMesh::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 MEDFileUMesh(fid,mName,dt,it); +} + +MEDFileUMesh *MEDFileUMesh::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 MEDFileUMesh(fid,ms.front().c_str(),dt,it); +} + +MEDFileUMesh *MEDFileUMesh::New() +{ + return new MEDFileUMesh; +} + +bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileMesh::isEqual(other,eps,what)) + return false; + const MEDFileUMesh *otherC=dynamic_cast(other); + if(!otherC) + { + what="Mesh types differ ! This is unstructured and other is NOT !"; + return false; + } + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const DataArrayDouble *coo1=_coords; + const DataArrayDouble *coo2=otherC->_coords; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) + { + what="Mismatch of coordinates ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(*coo2,eps); + if(!ret) + { + what="Coords differ !"; + return false; + } + } + const DataArrayInt *famc1=_fam_coords; + const DataArrayInt *famc2=otherC->_fam_coords; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on node differ !"; + return false; + } + } + const DataArrayInt *numc1=_num_coords; + const DataArrayInt *numc2=otherC->_num_coords; + if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(numc1) + { + bool ret=numc1->isEqual(*numc2); + if(!ret) + { + what="Numbering arr on node differ !"; + return false; + } + } + if(_ms.size()!=otherC->_ms.size()) + { + what="Number of levels differs !"; + return false; + } + std::size_t sz=_ms.size(); + for(std::size_t i=0;i_ms[i]; + if((s1==0 && s2!=0) || (s1!=0 && s2==0)) + { + what="Mismatch of presence of sub levels !"; + return false; + } + if(s1) + { + bool ret=s1->isEqual(s2,eps,what); + if(!ret) + return false; + } + } + std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; + return true; +} + +void MEDFileUMesh::clearNonDiscrAttributes() const +{ + MEDFileMesh::clearNonDiscrAttributes(); + const DataArrayDouble *coo1=_coords; + if(coo1) + ((DataArrayDouble *)coo1)->setName("");//This parameter is not discriminant for comparison + const DataArrayInt *famc1=_fam_coords; + if(famc1) + ((DataArrayInt *)famc1)->setName("");//This parameter is not discriminant for comparison + const DataArrayInt *numc1=_num_coords; + if(numc1) + ((DataArrayInt *)numc1)->setName("");//This parameter is not discriminant for comparison + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + const MEDFileUMeshSplitL1 *tmp=(*it); + if(tmp) + tmp->clearNonDiscrAttributes(); + } +} + +MEDFileUMesh::MEDFileUMesh() +{ +} + +MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +try + { + loadUMeshFromFile(fid,mName,dt,it); + } +catch(INTERP_KERNEL::Exception& e) + { + throw e; + } + +void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +{ + MEDFileUMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dummy2; + int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + if(meshType!=UNSTRUCTURED) + { + std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadAll(fid,mid,mName,dt,it); + int lev=loaderl2.getNumberOfLevels(); + _ms.resize(lev); + for(int i=0;i(this))->addFamily(DFT_FAM_NAME,0); + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + std::ostringstream oss; oss << "MEDFileUMesh : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); + const DataArrayDouble *coo=_coords; + INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_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); + int spaceDim=coo?coo->getNumberOfComponents():0; + int mdim=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;igetInfoOnComponent(i); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_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,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit); + MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + (*it)->write(fid,maa,mdim); + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str); +} + +std::vector MEDFileUMesh::getNonEmptyLevels() const +{ + std::vector ret; + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + if(!(*it)->empty()) + ret.push_back(lev); + return ret; +} + +std::vector MEDFileUMesh::getNonEmptyLevelsExt() const +{ + std::vector ret0=getNonEmptyLevels(); + if((const DataArrayDouble *) _coords) + { + std::vector ret(ret0.size()+1); + ret[0]=1; + std::copy(ret0.begin(),ret0.end(),ret.begin()+1); return ret; } - std::vector famIds=getFamiliesIds(fams); + return ret0; +} + +int MEDFileUMesh::getMeshDimension() const +{ + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + return (*it)->getMeshDimension()+lev; + throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); +} + +int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt==1) + { + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !"); + return _coords->getNumberOfTuples(); + } + return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize(); +} + +const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt==1) + { + if(!((const DataArrayInt *)_fam_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamilyFieldAtLevel : no coordinates specified !"); + return _fam_coords; + } const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getFamilyPart(famIds,renum); + return l1->getFamilyField(); } -DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) { - std::vector famIds=getFamiliesIds(fams); if(meshDimRelToMaxExt==1) { - MEDCouplingAutoRefCountObjectPtr da=_fam_coords->getIdsEqualList(famIds); - return MEDFileUMeshSplitL1::Renumber(_num_coords,da); + if(!((const DataArrayInt *)_num_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getNumberFieldAtLevel : no coordinates renum specified !"); + return _num_coords; } const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getFamilyPartArr(famIds,renum); + return l1->getNumberField(); +} + +const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt==1) + { + if(!((const DataArrayInt *)_num_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); + return _rev_num_coords; + } + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getRevNumberField(); +} + +DataArrayDouble *MEDFileUMesh::getCoords() const +{ + MEDCouplingAutoRefCountObjectPtr tmp(_coords); + if((DataArrayDouble *)tmp) + { + tmp->incrRef(); + return tmp; + } + return 0; } -DataArrayInt *MEDFileUMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception) { + synchronizeTinyInfoOnLeaves(); std::vector tmp(1); tmp[0]=grp; - DataArrayInt *ret=getNodeGroupsArr(tmp,renum); + MEDCouplingUMesh *ret=getGroups(meshDimRelToMaxExt,tmp,renum); ret->setName(grp); return ret; } -DataArrayInt *MEDFileUMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const throw(INTERP_KERNEL::Exception) { - return getGroupsArr(1,grps,renum); + synchronizeTinyInfoOnLeaves(); + std::set fams; + for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) + { + std::map >::const_iterator it2=_groups.find(*it); + if(it2==_groups.end()) + { + std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + fams.insert((*it2).second.begin(),(*it2).second.end()); + } + std::vector fams2(fams.begin(),fams.end()); + return getFamilies(meshDimRelToMaxExt,fams2,renum); } -DataArrayInt *MEDFileUMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception) { + synchronizeTinyInfoOnLeaves(); std::vector tmp(1); tmp[0]=fam; - DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); + MEDCouplingUMesh *ret=getFamilies(meshDimRelToMaxExt,tmp,renum); ret->setName(fam); return ret; } -DataArrayInt *MEDFileUMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) +{ + synchronizeTinyInfoOnLeaves(); + if(meshDimRelToMaxExt==1) + { + MEDCouplingAutoRefCountObjectPtr arr=getFamiliesArr(1,fams,renum); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); + ret->setCoords(c); + ret->incrRef(); + return ret; + } + std::vector famIds=getFamiliesIds(fams); + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getFamilyPart(famIds,renum); +} + +DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const throw(INTERP_KERNEL::Exception) { - return getFamiliesArr(1,fams,renum); + std::vector famIds=getFamiliesIds(fams); + if(meshDimRelToMaxExt==1) + { + if((const DataArrayInt *)_fam_coords) + { + MEDCouplingAutoRefCountObjectPtr da=_fam_coords->getIdsEqualList(famIds); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_coords,da); + else + { + da->incrRef(); + return da; + } + } + else + throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !"); + } + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getFamilyPartArr(famIds,renum); } MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception) { + synchronizeTinyInfoOnLeaves(); if(meshDimRelToMaxExt==1) { if(!renum) @@ -520,6 +1022,7 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu MEDCouplingUMesh *umesh=MEDCouplingUMesh::New(); MEDCouplingAutoRefCountObjectPtr cc=_coords->deepCpy(); umesh->setCoords(cc); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); return umesh; } } @@ -527,6 +1030,11 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu return l1->getWholeMesh(renum); } +MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) +{ + return getMeshAtLevel(meshDimRelToMax,false); +} + MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception) { return getMeshAtLevel(0,renum); @@ -547,20 +1055,6 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KE return getMeshAtLevel(-3,renum); } -bool MEDFileUMesh::existsFamily(int famId) const -{ - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - return true; - return false; -} - -bool MEDFileUMesh::existsFamily(const char *familyName) const -{ - std::string fname(familyName); - return _families.find(fname)!=_families.end(); -} - const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) { if(meshDimRelToMaxExt==1) @@ -616,50 +1110,6 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Excep _fam_coords->fillWithZero(); } -void MEDFileUMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) throw(INTERP_KERNEL::Exception) -{ - if(grps.empty()) - return ; - std::set grpsName; - std::vector grpsName2(grps.size()); - int i=0; - - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) - { - grpsName.insert((*it)->getName()); - grpsName2[i]=(*it)->getName(); - } - if(grpsName.size()!=grps.size()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !"); - if(grpsName.find(std::string(""))!=grpsName.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !"); - int sz=getSizeAtLevel(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr fam; - std::vector< std::vector > fidsOfGroups; - if(!renum) - { - fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); - } - else - { - std::vector< MEDCouplingAutoRefCountObjectPtr > grps2(grps.size()); - for(unsigned int i=0;isetName(grps[i]->getName().c_str()); - } - std::vector grps3(grps2.begin(),grps2.end()); - fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); - } - int offset=1; - if(!_families.empty()) - offset=getMaxFamilyId()+1; - TranslateFamilyIds(offset,fam,fidsOfGroups); - std::set ids=fam->getDifferentValues(); - appendFamilyEntries(ids,fidsOfGroups,grpsName2); - setFamilyArr(meshDimRelToMaxExt,fam); -} - void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception) { if(meshDimRelToMaxExt==1) @@ -726,22 +1176,6 @@ void MEDFileUMesh::addNodeGroup(const std::string& name, const std::vector& } -void MEDFileUMesh::copyFamGrpMapsFrom(const MEDFileUMesh& other) -{ - _groups=other._groups; - _families=other._families; -} - -void MEDFileUMesh::setFamilyInfo(const std::map& info) -{ - _families=info; -} - -void MEDFileUMesh::setGroupInfo(const std::map >&info) -{ - _groups=info; -} - void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception) { std::string oldName=getFamilyNameGivenId(id); @@ -846,7 +1280,7 @@ void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms) const throw(INTERP_KERNEL::Exception) { - DataArrayDouble *ret=ms[0]->getCoords(); + const DataArrayDouble *ret=ms[0]->getCoords(); int mdim=ms[0]->getMeshDimension(); for(unsigned int i=1;igetMeshDimension()!=mdim) throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !"); } - return ret; + return const_cast(ret); } -void MEDFileUMesh::setFamilyArr(int meshDimRelToMaxExt, DataArrayInt *famArr) +void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) { if(meshDimRelToMaxExt==1) { @@ -868,7 +1302,7 @@ void MEDFileUMesh::setFamilyArr(int meshDimRelToMaxExt, DataArrayInt *famArr) return ; } if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyArr : Dimension request is invalid (>1) !"); + throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); int traducedRk=-meshDimRelToMaxExt; if(traducedRk>=(int)_ms.size()) throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !"); @@ -877,7 +1311,7 @@ void MEDFileUMesh::setFamilyArr(int meshDimRelToMaxExt, DataArrayInt *famArr) return _ms[traducedRk]->setFamilyArr(famArr); } -void MEDFileUMesh::setRenumArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) +void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) { if(meshDimRelToMaxExt==1) { @@ -897,74 +1331,447 @@ void MEDFileUMesh::setRenumArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) return _ms[traducedRk]->setRenumArr(renumArr); } -void MEDFileUMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) +void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const { - famArr->applyLin(1,offset,0); - for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus(),offset)); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)) + (*it)->synchronizeTinyInfo(*this); } -/*! - * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids - * not in '_families'. Groups information are given in parameters in order to give to families representative names. - * For the moment, the two last input parameters are not taken into account. - */ -void MEDFileUMesh::appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) +void MEDFileUMesh::computeRevNum() const { - std::map famInv; - for(std::set::const_iterator it=famIds.begin();it!=famIds.end();it++) + if((const DataArrayInt *)_num_coords) { - std::ostringstream oss; - oss << "Family_" << (*it); - _families[oss.str()]=(*it); - famInv[*it]=oss.str(); + int pos; + int maxValue=_num_coords->getMaxValue(pos); + _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); } - int i=0; - for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) +} + +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()) { - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + 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); +} + +bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileMesh::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) { - _groups[grpNames[i]].push_back(famInv[*it2]); + 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)) + { + what="Mismatch of families arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on nodes differ !"; + return false; + } + } + famc1=_fam_cells; + famc2=otherC->_fam_cells; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on cells ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on cells differ !"; + return false; + } + } + famc1=_num_nodes; + famc2=otherC->_num_nodes; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on nodes differ !"; + return false; + } + } + famc1=_num_cells; + famc2=otherC->_num_cells; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on cells ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on cells differ !"; + return false; } } + return true; } -/*! - * This method appends a new entry in _families attribute. An exception is thrown if either the famId is already - * kept by an another familyName. An exception is thrown if name 'familyName' is alreadyset with a different 'famId'. - */ -void MEDFileUMesh::addFamily(int famId, const char *familyName) throw(INTERP_KERNEL::Exception) +void MEDFileCMesh::clearNonDiscrAttributes() const { - std::string fname(familyName); - std::map::const_iterator it=_families.find(fname); - if(it==_families.end()) + MEDFileMesh::clearNonDiscrAttributes(); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh); + const DataArrayInt *tmp=_fam_nodes; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_num_nodes; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_fam_cells; + if(tmp) + (const_cast(tmp))->setName(""); + tmp=_num_cells; + if(tmp) + (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) +{ + MEDFileCMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dtunit; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + if(meshType!=CARTESIAN) { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileUMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; + 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) + { + _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 spaceDim=mesh->getSpaceDimension(); + 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) !"); + } + nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + _fam_cells=DataArrayInt::New(); + _fam_cells->alloc(nbOfElt,1); + MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer()); + } + nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + _num_cells=DataArrayInt::New(); + _num_cells->alloc(nbOfElt,1); + MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer()); + } +} + +const MEDCouplingCMesh *MEDFileCMesh::getMesh() const +{ + synchronizeTinyInfoOnLeaves(); + return _cmesh; +} + +MEDCouplingMesh *MEDFileCMesh::getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) +{ + 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); +} + +void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) +{ + if(m) + m->incrRef(); + _cmesh=m; +} + +void MEDFileCMesh::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +{ + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileCMesh : name is empty. MED file ask for a NON EMPTY name !"); + if(!existsFamily(0)) + (const_cast(this))->addFamily(DFT_FAM_NAME,0); + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + std::ostringstream oss; oss << "MEDFileCMesh : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str()); + 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=_cmesh->getSpaceDimension(); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + for(int i=0;igetCoordsAt(i)->getInfoOnComponent(0)); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_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,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit); + MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID); + for(int i=0;igetCoordsAt(i); + MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()); } + if((const DataArrayInt *)_fam_cells) + MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,MED_GEO_ALL,_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(); +} + +void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const +{ + const MEDCouplingCMesh *cmesh=_cmesh; + (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()); +} + +DataArrayInt *MEDFileCMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) 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) { - if((*it).second!=famId) + if((const DataArrayInt *)_fam_nodes) { - std::ostringstream oss; - oss << "MEDFileUMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + MEDCouplingAutoRefCountObjectPtr da=_fam_nodes->getIdsEqualList(famIds); + 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 !"); + } + else + { + if((const DataArrayInt *)_fam_cells) + { + MEDCouplingAutoRefCountObjectPtr da=_fam_cells->getIdsEqualList(famIds); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + { + da->incrRef(); + return da; + } } + else + throw INTERP_KERNEL::Exception("MEDFileCMesh::getFamiliesArr : no family array specified on cells !"); } } -void MEDFileUMesh::computeRevNum() const +void MEDFileCMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) { - if((const DataArrayInt *)_num_coords) + 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; +} + +void MEDFileCMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) +{ + 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 DataArrayInt *MEDFileCMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + 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; +} + +const DataArrayInt *MEDFileCMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const 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; +} + +const DataArrayInt *MEDFileCMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); + if(meshDimRelToMaxExt==0) { - int pos; - int maxValue=_num_coords->getMaxValue(pos); - _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); + 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 !"); } } diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index 64b05dfa6..98b42f6de 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -29,81 +29,130 @@ namespace ParaMEDMEM class MEDFileMesh : public RefCountObject { public: - static MEDFileMesh *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + 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); + virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + virtual void clearNonDiscrAttributes() const; void setName(const char *name) { _name=name; } const char *getName() const { return _name.c_str(); } void setUnivName(const char *name) { _univ_name=name; } const char *getUnivName() const { return _univ_name.c_str(); } void setDescription(const char *name) { _desc_name=name; } const char *getDescription() const { return _desc_name.c_str(); } + void setOrder(int order) { _order=order; } + int getOrder() const { return _order; } + void setIteration(int it) { _iteration=it; } + int getIteration() const { return _iteration; } + void setTimeValue(double time) { _time=time; } + void setTime(double time, int dt, int it) { _time=time; _iteration=dt; _order=it; } + double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } + double getTimeValue() const { return _time; } + void setTimeUnit(const char *unit) { _dt_unit=unit; } + const char *getTimeUnit() const { return _dt_unit.c_str(); } + virtual void write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) = 0; + virtual int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) = 0; + // + bool areFamsEqual(const MEDFileMesh *other, std::string& what) const; + bool areGrpsEqual(const MEDFileMesh *other, std::string& what) const; + bool existsFamily(int famId) const; + bool existsFamily(const char *familyName) const; + void setFamilyId(const char *familyName, int id); + void addFamily(const char *familyName, int id) throw(INTERP_KERNEL::Exception); + void addGrpOnFamily(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception); + void setFamilyInfo(const std::map& info); + void setGroupInfo(const std::map >&info); + void copyFamGrpMapsFrom(const MEDFileMesh& other); + const std::map& getFamilyInfo() const { return _families; } + const std::map >& getGroupInfo() const { return _groups; } + std::vector getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception); + std::vector getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception); + std::vector getGroupsNames() const; + std::vector getFamiliesNames() const; + void removeGroup(const char *name) throw(INTERP_KERNEL::Exception); + void removeFamily(const char *name) throw(INTERP_KERNEL::Exception); + void changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); + void changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception); + int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); + int getMaxFamilyId() 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); + // + virtual void setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) throw(INTERP_KERNEL::Exception); + virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) = 0; + virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) = 0; + virtual const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) = 0; + virtual const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) = 0; + virtual const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupArr(const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamilyArr(const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); protected: + MEDFileMesh(); + virtual void synchronizeTinyInfoOnLeaves() const = 0; + virtual void appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); + static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); + protected: + int _order; + int _iteration; + double _time; + std::string _dt_unit; std::string _name; std::string _univ_name; std::string _desc_name; + protected: + std::map > _groups; + std::map _families; + protected://policies on write + int _too_long_str; + int _zipconn_pol; + public: + static const char DFT_FAM_NAME[]; }; class MEDFileUMesh : public MEDFileMesh { + friend class MEDFileMesh; public: - static MEDFileUMesh *New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + 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(); + bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; ~MEDFileUMesh(); // - void removeGroup(const char *name) throw(INTERP_KERNEL::Exception); - void removeFamily(const char *name) throw(INTERP_KERNEL::Exception); - 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 write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception); - int getMaxFamilyId() 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); int getMeshDimension() const; int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); 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); - std::vector getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception); - std::vector getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception); - std::vector getGroupsNames() const; - std::vector getFamiliesNames() const; std::vector getNonEmptyLevels() const; std::vector getNonEmptyLevelsExt() const; DataArrayDouble *getCoords() const; MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeGroupArr(const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeFamilyArr(const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - const std::map& getFamilyInfo() const { return _families; } - const std::map >& getGroupInfo() const { return _groups; } - bool existsFamily(int famId) const; - bool existsFamily(const char *familyName) const; // - void copyFamGrpMapsFrom(const MEDFileUMesh& other); - void setFamilyInfo(const std::map& info); - void setGroupInfo(const std::map >&info); void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - void setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) throw(INTERP_KERNEL::Exception); void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); void setFamilyField(DataArrayInt *arr, const std::vector< std::vector< int > > &userfids, const std::vector& grpNames, bool renum=false) throw(INTERP_KERNEL::Exception); - void setFamilyArr(int meshDimRelToMaxExt, DataArrayInt *famArr); - void setRenumArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); + 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 setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); void setMeshAtLevelOld(int meshDimRelToMax, MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); @@ -111,32 +160,58 @@ namespace ParaMEDMEM 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 addFamily(int famId, const char *familyName) throw(INTERP_KERNEL::Exception); private: MEDFileUMesh(); - MEDFileUMesh(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception); + MEDFileUMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); + void loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); void checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); DataArrayDouble *checkMultiMesh(const std::vector& ms) const throw(INTERP_KERNEL::Exception); - void appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); void computeRevNum() const; - static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); + void synchronizeTinyInfoOnLeaves() const; private: - std::map > _groups; - std::map _families; std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; MEDCouplingAutoRefCountObjectPtr _coords; MEDCouplingAutoRefCountObjectPtr _fam_coords; MEDCouplingAutoRefCountObjectPtr _num_coords; mutable MEDCouplingAutoRefCountObjectPtr _rev_num_coords; - int _too_long_str; - int _zipconn_pol; }; class MEDFileCMesh : public MEDFileMesh { + 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); + bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; + const MEDCouplingCMesh *getMesh() const; + MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); + void setMesh(MEDCouplingCMesh *m); + void write(const char *fileName, int mode) const 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); + 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); + private: + 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); + 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; }; } diff --git a/src/MEDLoader/MEDFileMeshElt.cxx b/src/MEDLoader/MEDFileMeshElt.cxx index 9fa3dfbe0..2e512a448 100644 --- a/src/MEDLoader/MEDFileMeshElt.cxx +++ b/src/MEDLoader/MEDFileMeshElt.cxx @@ -24,25 +24,27 @@ #include "InterpKernelAutoPtr.hxx" #include "CellModel.hxx" -extern med_geometrie_element typmai3[32]; +extern med_geometry_type typmai3[32]; using namespace ParaMEDMEM; -MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int mdim, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType geoElt2) +MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2) { - med_entite_maillage whichEntity; - if(!isExisting(fid,mName,geoElt,whichEntity)) + med_entity_type whichEntity; + if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) return 0; - return new MEDFileUMeshPerType(fid,mName,mdim,geoElt,geoElt2,whichEntity); + return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity); } -bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, med_geometrie_element geoElt, med_entite_maillage& whichEntity) +bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity) { - static const med_entite_maillage entities[3]={MED_MAILLE,MED_FACE,MED_ARETE}; + static const med_entity_type entities[1]={MED_CELL}; int nbOfElt=0; - for(int i=0;i<3;i++) + for(int i=0;i<1;i++) { - int tmp=MEDnEntMaa(fid,(char *)mName,MED_CONN,entities[i],geoElt,MED_NOD); + med_bool changement,transformation; + int tmp=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoElt,MED_CONNECTIVITY,MED_NODAL, + &changement,&transformation); if(tmp>nbOfElt) { nbOfElt=tmp; @@ -58,41 +60,42 @@ int MEDFileUMeshPerType::getDim() const return cm.getDimension(); } -MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int mdim, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entite_maillage entity):_type(type),_entity(entity) +MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity):_type(type),_entity(entity) { - int curNbOfElem=MEDnEntMaa(fid,(char *)mName,MED_CONN,entity,geoElt,MED_NOD); + med_bool changement,transformation; + int curNbOfElem=MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL, + &changement,&transformation); if(type!=INTERP_KERNEL::NORM_POLYGON && type!=INTERP_KERNEL::NORM_POLYHED) { - loadFromStaticType(fid,mName,mdim,curNbOfElem,geoElt,type,entity); + loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity); return; } if(type==INTERP_KERNEL::NORM_POLYGON) { - loadPolyg(fid,mName,mdim,curNbOfElem,geoElt,entity); + loadPolyg(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity); return; } //if(type==INTERP_KERNEL::NORM_POLYHED) - loadPolyh(fid,mName,mdim,curNbOfElem,geoElt,entity); + loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity); } -void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entite_maillage entity) +void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity) { _conn=DataArrayInt::New(); int nbOfNodesPerCell=(geoElt%100); _conn->alloc((nbOfNodesPerCell+1)*curNbOfElem,1); _conn_index=DataArrayInt::New(); _conn_index->alloc(curNbOfElem+1,1); - int *connTab=new int[(nbOfNodesPerCell)*curNbOfElem]; + INTERP_KERNEL::AutoPtr connTab=new int[(nbOfNodesPerCell)*curNbOfElem]; _num=DataArrayInt::New(); _num->alloc(curNbOfElem,1); - char *noms=new char[MED_TAILLE_PNOM*curNbOfElem+1]; - med_booleen inoele, inuele; _fam=DataArrayInt::New(); _fam->alloc(curNbOfElem,1); - MEDelementsLire(fid,(char *)mName,mdim,connTab,MED_FULL_INTERLACE,noms,&inoele,_num->getPointer(),&inuele,_fam->getPointer(),curNbOfElem,entity,geoElt,MED_NOD); - delete [] noms; + med_bool withname=MED_FALSE,withnumber=MED_FALSE,withfam=MED_FALSE; + INTERP_KERNEL::AutoPtr noms=new char[MED_SNAME_SIZE*curNbOfElem+1]; + MEDmeshElementRd(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,connTab,&withname,noms,&withnumber,_num->getPointer(),&withfam,_fam->getPointer()); int *w1=_conn->getPointer(); int *w2=_conn_index->getPointer(); *w2++=0; @@ -103,16 +106,15 @@ void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int w1=std::transform(wi,wi+nbOfNodesPerCell,w1,std::bind2nd(std::plus(),-1)); *w2=w2[-1]+nbOfNodesPerCell+1; } - delete [] connTab; - if(!inuele) + if(!withnumber) _num=0; } -void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, - med_entite_maillage entity) +void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, + med_entity_type entity) { - med_int arraySize; - MEDpolygoneInfo(fid,(char *)mName,entity,MED_NOD,&arraySize); + med_bool changement,transformation; + med_int curNbOfElem=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1; _conn_index=DataArrayInt::New(); _conn_index->alloc(curNbOfElem+1,1); _conn=DataArrayInt::New(); @@ -121,8 +123,8 @@ void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int mdim, in _num->alloc(curNbOfElem,1); _fam=DataArrayInt::New(); _fam->alloc(curNbOfElem,1); - int *locConn=new int[arraySize]; - MEDpolygoneConnLire(fid,(char *)mName,_conn_index->getPointer(),curNbOfElem+1,locConn,entity,MED_NOD); + INTERP_KERNEL::AutoPtr locConn=new int[arraySize]; + MEDmeshPolygonRd(fid,mName,dt,it,MED_CELL,MED_NODAL,_conn_index->getPointer(),locConn); int *w1=_conn->getPointer(); int *w2=_conn_index->getPointer(); const int *wi=locConn; @@ -133,24 +135,41 @@ void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int mdim, in *w2=*w2-1+i; } *w2=*w2-1+curNbOfElem; - delete [] locConn; - MEDfamLire(fid,(char *)mName,_fam->getPointer(),curNbOfElem,entity,MED_POLYGONE); - if(MEDnumLire(fid,(char *)mName,_num->getPointer(),curNbOfElem,entity,MED_POLYGONE)!=0) + if(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYGON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,MED_POLYGON,_fam->getPointer())!=0) + std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); + } + else + std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); + if(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYGON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,MED_POLYGON,_num->getPointer())!=0) + _num=0; + } + else _num=0; } -void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, - med_entite_maillage entity) +void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, + med_entity_type entity) { - med_int indexFaceLgth,connFaceLgth; - MEDpolyedreInfo(fid,(char*)mName,MED_NOD,&indexFaceLgth,&connFaceLgth); - int *index=new int[curNbOfElem+1]; - int *indexFace=new int[indexFaceLgth]; - int *locConn=new int[connFaceLgth]; + med_bool changement,transformation; + med_int indexFaceLgth=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation); + int curNbOfElem=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1; + INTERP_KERNEL::AutoPtr index=new int[curNbOfElem+1]; + INTERP_KERNEL::AutoPtr indexFace=new int[indexFaceLgth]; + INTERP_KERNEL::AutoPtr locConn=new int[connFaceLgth]; _fam=DataArrayInt::New(); _fam->alloc(curNbOfElem,1); - MEDpolyedreConnLire(fid,(char *)mName,index,curNbOfElem+1,indexFace,indexFaceLgth,locConn,MED_NOD); - MEDfamLire(fid,(char *)mName,_fam->getPointer(),curNbOfElem,MED_MAILLE,MED_POLYEDRE); + MEDmeshPolyhedronRd(fid,mName,dt,it,MED_CELL,MED_NODAL,index,indexFace,locConn); + if(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,_fam->getPointer())!=0) + std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); + } + else + std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); int arraySize=connFaceLgth; for(int i=0;i(),-1)); } } - delete [] index; - delete [] locConn; - delete [] indexFace; _num=DataArrayInt::New(); _num->alloc(curNbOfElem,1); - if(MEDnumLire(fid,(char *)mName,_num->getPointer(),curNbOfElem,MED_MAILLE,MED_POLYEDRE)!=0) + if(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,MED_POLYHEDRON,_num->getPointer())!=0) + _num=0; + } + else _num=0; } @@ -186,9 +207,11 @@ void MEDFileUMeshPerType::write(med_idt fid, const char *mname, int mdim, const int nbOfCells=m->getNumberOfCells(); if(nbOfCells<1) return ; + int dt,it; + double timm=m->getTime(dt,it); INTERP_KERNEL::NormalizedCellType ikt=m->getTypeOfCell(0); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(ikt); - med_geometrie_element curMedType=typmai3[(int)ikt]; + med_geometry_type curMedType=typmai3[(int)ikt]; const int *conn=m->getNodalConnectivity()->getConstPointer(); const int *connI=m->getNodalConnectivityIndex()->getConstPointer(); if(ikt!=INTERP_KERNEL::NORM_POLYGON && ikt!=INTERP_KERNEL::NORM_POLYHED) @@ -198,7 +221,7 @@ void MEDFileUMeshPerType::write(med_idt fid, const char *mname, int mdim, const int *w=tab; for(int i=0;i(),1)); - MEDconnEcr(fid,(char *)mname,mdim,tab,MED_FULL_INTERLACE,nbOfCells,MED_MAILLE,curMedType,MED_NOD); + MEDmeshElementConnectivityWr(fid,mname,dt,it,timm,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfCells,tab); } else { @@ -213,7 +236,7 @@ void MEDFileUMeshPerType::write(med_idt fid, const char *mname, int mdim, const wI[1]=wI[0]+connI[i+1]-connI[i]-1; w=std::transform(conn+connI[i]+1,conn+connI[i+1],w,std::bind2nd(std::plus(),1)); } - MEDpolygoneConnEcr(fid,(char *)mname,tab1,nbOfCells,tab2,MED_MAILLE,MED_NOD); + MEDmeshPolygonWr(fid,mname,dt,it,timm,MED_CELL,MED_NODAL,nbOfCells+1,tab1,tab2); } else { @@ -242,12 +265,11 @@ void MEDFileUMeshPerType::write(med_idt fid, const char *mname, int mdim, const } w1[1]=w1[0]+nbOfFaces; } - MEDpolyedreConnEcr(fid,(char *)mname,tab1,nbOfCells+1,tab2,nbOfFaces+1, - bigtab,MED_NOD); + MEDmeshPolyhedronWr(fid,mname,dt,it,timm,MED_CELL,MED_NODAL,nbOfCells+1,tab1,nbOfFaces+1,tab2,bigtab); } } if(fam) - MEDfamEcr(fid,(char *)mname,(int *)fam->getConstPointer(),nbOfCells,MED_MAILLE,curMedType); + MEDmeshEntityFamilyNumberWr(fid,mname,dt,it,MED_CELL,curMedType,nbOfCells,fam->getConstPointer()); if(num) - MEDnumEcr(fid,(char *)mname,(int *)num->getConstPointer(),nbOfCells,MED_MAILLE,curMedType); + MEDmeshEntityNumberWr(fid,mname,dt,it,MED_CELL,curMedType,nbOfCells,num->getConstPointer()); } diff --git a/src/MEDLoader/MEDFileMeshElt.hxx b/src/MEDLoader/MEDFileMeshElt.hxx index 732ca2b43..ff79d1bbc 100644 --- a/src/MEDLoader/MEDFileMeshElt.hxx +++ b/src/MEDLoader/MEDFileMeshElt.hxx @@ -37,8 +37,8 @@ namespace ParaMEDMEM class MEDFileUMeshPerType : public RefCountObject { public: - static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int mdim, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType geoElt2); - static bool isExisting(med_idt fid, const char *mName, med_geometrie_element geoElt, med_entite_maillage& whichEntity); + 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); int getDim() const; const DataArrayInt *getNodal() const { return _conn; } const DataArrayInt *getNodalIndex() const { return _conn_index; } @@ -46,21 +46,21 @@ namespace ParaMEDMEM const DataArrayInt *getNum() const { return _num; } static void write(med_idt fid, const char *mname, int mdim, const MEDCouplingUMesh *m, const DataArrayInt *fam, const DataArrayInt *num); private: - MEDFileUMeshPerType(med_idt fid, const char *mName, int mdim, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entite_maillage entity); - void loadFromStaticType(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entite_maillage entity); - void loadPolyg(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, - med_entite_maillage entity); - void loadPolyh(med_idt fid, const char *mName, int mdim, int curNbOfElem, med_geometrie_element geoElt, - med_entite_maillage entity); + MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity); + void loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity); + void loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, + med_entity_type entity); + void loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, + med_entity_type entity); private: MEDCouplingAutoRefCountObjectPtr _conn; MEDCouplingAutoRefCountObjectPtr _conn_index; MEDCouplingAutoRefCountObjectPtr _num; MEDCouplingAutoRefCountObjectPtr _fam; INTERP_KERNEL::NormalizedCellType _type; - med_entite_maillage _entity; + med_entity_type _entity; }; } diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx index e0e7840f4..83caf3aa2 100644 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ b/src/MEDLoader/MEDFileMeshLL.cxx @@ -18,6 +18,7 @@ // #include "MEDFileMeshLL.hxx" +#include "MEDFileMesh.hxx" #include "MEDLoaderBase.hxx" #include "MEDCouplingUMesh.hxx" @@ -26,108 +27,37 @@ #include -extern med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2]; -extern med_geometrie_element typmainoeud[1]; +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmainoeud[1]; using namespace ParaMEDMEM; -MEDFileMeshL2::MEDFileMeshL2():_name(MED_TAILLE_NOM),_description(MED_TAILLE_DESC) +MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_dt_unit(MED_LNAME_SIZE) { } -MEDFileUMeshL2::MEDFileUMeshL2() -{ -} - -void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const char *mName) -{ - _name.set(mName); - med_maillage type_maillage; - med_int Mdim; - if(MEDmaaInfo(fid,mId,(char *)mName,&Mdim,&type_maillage,_description.getPointer())!=0) - throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !"); - if(type_maillage!=MED_NON_STRUCTURE) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); - loadConnectivity(fid,Mdim,mName); - loadCoords(fid,mId,Mdim,mName); -} - -void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const char *mName) -{ - _per_type_mesh.resize(1); - _per_type_mesh[0].clear(); - for(int j=0;jalloc(nCoords,spaceDim); - double *coordsPtr=_coords->getPointer(); - med_repere repere; - char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - MEDcoordLire(fid,(char *)mName,spaceDim,coordsPtr,MED_FULL_INTERLACE,MED_ALL,NULL,0,&repere,comp,unit); - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nCoords,1); - _num_coords=DataArrayInt::New(); - _num_coords->alloc(nCoords,1); - MEDfamLire(fid,(char *)mName,_fam_coords->getPointer(),nCoords,MED_NOEUD,MED_NONE); - if(MEDnumLire(fid,(char *)mName,_num_coords->getPointer(),nCoords,MED_NOEUD,MED_NONE)!=0) - _num_coords=0; - for(int i=0;isetInfoOnComponent(i,info.c_str()); - } - delete [] comp; - delete [] unit; -} - -void MEDFileUMeshL2::sortTypes() +int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const char *mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) throw(INTERP_KERNEL::Exception) { - std::set mdims; - std::vector< MEDCouplingAutoRefCountObjectPtr > tmp(_per_type_mesh[0]); - _per_type_mesh.clear(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - mdims.insert((*it)->getDim()); - if(mdims.empty()) - return; - int mdim=*mdims.rbegin(); - _per_type_mesh.resize(mdim+1); - for(int dim=mdim+1;dim!=0;dim--) - { - std::vector< MEDCouplingAutoRefCountObjectPtr >& elt=_per_type_mesh[mdim+1-dim]; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - if((*it)->getDim()==dim-1) - elt.push_back(*it); - } -} - -int MEDFileUMeshL2::getMeshIdFromName(med_idt fid, const char *mname) throw(INTERP_KERNEL::Exception) -{ - med_maillage type_maillage; - char maillage_description[MED_TAILLE_DESC+1]; - med_int dim; - char nommaa[MED_TAILLE_NOM+1]; - med_int n=MEDnMaa(fid); + med_mesh_type type_maillage; + char maillage_description[MED_COMMENT_SIZE+1]; + char dtunit[MED_LNAME_SIZE+1]; + med_int spaceDim,dim; + char nommaa[MED_NAME_SIZE+1]; + med_int n=MEDnMesh(fid); bool found=false; int ret=-1; + med_sorting_type stype; std::vector ms; - for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + MEDmeshInfo(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit); + dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit)); std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); ms.push_back(cur); if(cur==mname) @@ -143,38 +73,106 @@ int MEDFileUMeshL2::getMeshIdFromName(med_idt fid, const char *mname) throw(INTE std::copy(ms.begin(),ms.end(),std::ostream_iterator(oss,", ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } + switch(type_maillage) + { + case MED_UNSTRUCTURED_MESH: + meshType=UNSTRUCTURED; + break; + case MED_STRUCTURED_MESH: + meshType=CARTESIAN; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); + } + med_int numdt,numit; + med_float dtt; + MEDmeshComputationStepInfo(fid,mname,1,&numdt,&numit,&dtt); + dt=numdt; it=numit; return ret; } -void MEDFileUMeshL2::readFamiliesAndGrps(med_idt fid, const char *meshName, std::map& fams, std::map >& grps) +double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const char *mName, int nstep, int dt, int it) throw(INTERP_KERNEL::Exception) { - char nomfam[MED_TAILLE_NOM+1]; + bool found=false; + med_int numdt,numit; + med_float dtt; + std::vector< std::pair > p(nstep); + for(int i=0;i(numdt,numit); + found=(numdt==dt) && (numit==numit); + } + if(!found) + { + std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! "; + oss << "Possibilities are : "; + for(int i=0;i MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const char *mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) throw(INTERP_KERNEL::Exception) +{ + med_mesh_type type_maillage; + med_int spaceDim; + med_sorting_type stype; + med_axis_type axistype; + int naxis=MEDmeshnAxis(fid,mId); + INTERP_KERNEL::AutoPtr nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(), + &stype,&nstep,&axistype,axisname,axisunit)!=0) + throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !"); + switch(type_maillage) + { + case MED_UNSTRUCTURED_MESH: + meshType=UNSTRUCTURED; + break; + case MED_STRUCTURED_MESH: + meshType=CARTESIAN; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); + } + // + std::vector infosOnComp(naxis); + for(int i=0;i& fams, std::map >& grps) +{ + char nomfam[MED_NAME_SIZE+1]; med_int numfam; - int nfam=MEDnFam(fid,(char *)meshName); + int nfam=MEDnFamily(fid,meshName); for(int i=0;i attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); + std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE); fams[famName]=numfam; for(int j=0;j& fams, const std::map >& grps, int tooLongStrPol) +void MEDFileMeshL2::WriteFamiliesAndGrps(med_idt fid, const char *mname, const std::map& fams, const std::map >& grps, int tooLongStrPol) { for(std::map::const_iterator it=fams.begin();it!=fams.end();it++) { @@ -185,35 +183,104 @@ void MEDFileUMeshL2::writeFamiliesAndGrps(med_idt fid, const char *mname, const grpsOfFam.push_back((*it1).first); } int ngro=grpsOfFam.size(); - INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_TAILLE_LNOM*ngro); + INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); int i=0; for(std::vector::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++) - MEDLoaderBase::safeStrCpy((*it2).c_str(),MED_TAILLE_LNOM-1,groName+i*MED_TAILLE_LNOM,tooLongStrPol); - INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_TAILLE_NOM,famName,tooLongStrPol); - MEDfamCr(fid,(char *)mname,famName,(*it).second,0,0,0,0,groName,ngro); + MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol); + INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol); + int ret=MEDfamilyCr(fid,mname,famName,(*it).second,ngro,groName); + ret++; } } -void MEDFileUMeshL2::writeCoords(med_idt fid, const char *mname, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords) +MEDFileUMeshL2::MEDFileUMeshL2() { - if(!coords) - return ; - int spaceDim=coords->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); +} + +void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, int it) +{ + _name.set(mName); + int nstep; + int Mdim; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); + if(meshType!=UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); + _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); + _iteration=dt; + _order=it; + loadConnectivity(fid,Mdim,mName,dt,it);//to improve check (dt,it) coherency + loadCoords(fid,mId,infosOnComp,mName,dt,it); +} + +void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const char *mName, int dt, int it) +{ + _per_type_mesh.resize(1); + _per_type_mesh[0].clear(); + for(int j=0;j& infosOnComp, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +{ + int spaceDim=infosOnComp.size(); + med_bool changement,transformation; + int nCoords=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation); + _coords=DataArrayDouble::New(); + _coords->alloc(nCoords,spaceDim); + double *coordsPtr=_coords->getPointer(); + MEDmeshNodeCoordinateRd(fid,mName,dt,it,MED_FULL_INTERLACE,coordsPtr); + _fam_coords=DataArrayInt::New(); + _fam_coords->alloc(nCoords,1); + _num_coords=DataArrayInt::New(); + _num_coords->alloc(nCoords,1); + if(MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer()); + else + _fam_coords=0; + if(MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer()); + else + _num_coords=0; for(int i=0;isetInfoOnComponent(i,infosOnComp[i].c_str()); +} + +void MEDFileUMeshL2::sortTypes() +{ + std::set mdims; + std::vector< MEDCouplingAutoRefCountObjectPtr > tmp(_per_type_mesh[0]); + _per_type_mesh.clear(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) + mdims.insert((*it)->getDim()); + if(mdims.empty()) + return; + int mdim=*mdims.rbegin(); + _per_type_mesh.resize(mdim+1); + for(int dim=mdim+1;dim!=0;dim--) { - std::string info=coords->getInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,0);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,0);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + std::vector< MEDCouplingAutoRefCountObjectPtr >& elt=_per_type_mesh[mdim+1-dim]; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) + if((*it)->getDim()==dim-1) + elt.push_back(*it); } - MEDcoordEcr(fid,(char *)mname,spaceDim,coords->getPointer(),MED_FULL_INTERLACE,coords->getNumberOfTuples(),MED_CART,comp,unit); - MEDfamEcr(fid,(char *)mname,famCoords->getPointer(),famCoords->getNumberOfTuples(),MED_NOEUD,MED_NONE); +} + +void MEDFileUMeshL2::WriteCoords(med_idt fid, const char *mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords) +{ + if(!coords) + return ; + MEDmeshNodeCoordinateWr(fid,mname,dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getPointer()); + if(famCoords) + MEDmeshEntityFamilyNumberWr(fid,mname,dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getPointer()); if(numCoords) - MEDnumEcr(fid,(char *)mname,numCoords->getPointer(),numCoords->getNumberOfTuples(),MED_NOEUD,MED_NONE); + MEDmeshEntityNumberWr(fid,mname,dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getPointer()); } bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const @@ -232,6 +299,56 @@ bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const return true; } +MEDFileCMeshL2::MEDFileCMeshL2() +{ +} + +void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception) +{ + _name.set(mName); + int nstep; + int Mdim; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); + if(meshType!=CARTESIAN) + 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; + // + 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 !"); + _cmesh=MEDCouplingCMesh::New(); + for(int i=0;i da=DataArrayDouble::New(); + da->alloc(nbOfElt,1); + da->setInfoOnComponent(0,infosOnComp[i].c_str()); + MEDmeshGridIndexCoordinateRd(fid,mName,dt,it,i+1,da->getPointer()); + _cmesh->setCoordsAt(i,da); + } +} + +med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) throw(INTERP_KERNEL::Exception) +{ + switch(id) + { + case 0: + return MED_COORDINATE_AXIS1; + case 1: + return MED_COORDINATE_AXIS2; + case 2: + return MED_COORDINATE_AXIS3; + default: + throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !"); + } +} + MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0) { } @@ -332,6 +449,76 @@ MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m( assignMesh(m,newOrOld); } +bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const +{ + const MEDCouplingUMesh *m1=_m_by_types; + const MEDCouplingUMesh *m2=other->_m_by_types; + if((m1==0 && m2!=0) || (m1!=0 && m2==0)) + { + what="Presence of mesh in one sublevel and not in other!"; + return false; + } + if(m1) + if(!m1->isEqual(m2,eps)) + { + what="meshes at a sublevel are not deeply equal !"; + return false; + } + const DataArrayInt *d1=_fam; + const DataArrayInt *d2=other->_fam; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Presence of family arr in one sublevel and not in other!"; + return false; + } + if(d1) + if(!d1->isEqual(*d2)) + { + what="family arr at a sublevel are not deeply equal !"; + return false; + } + d1=_num; + d2=other->_num; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Presence of cell numbering arr in one sublevel and not in other!"; + return false; + } + if(d1) + if(!d1->isEqual(*d2)) + { + what="Numbering cell arr at a sublevel are not deeply equal !"; + return false; + } + return true; +} + +void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const +{ + const MEDCouplingUMesh *tmp=_m_by_types; + if(!tmp) + return ; + (const_cast(tmp))->setName(master.getName()); + (const_cast(tmp))->setDescription(master.getDescription()); + (const_cast(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); + (const_cast(tmp))->setTimeUnit(master.getTimeUnit()); +} + +void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const +{ + ClearNonDiscrAttributes(_m_by_types); +} + +void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp) +{ + if(!tmp) + return ; + (const_cast(tmp))->setName(""); + (const_cast(tmp))->setDescription(""); + (const_cast(tmp))->setTime(0.,-1,-1); + (const_cast(tmp))->setTimeUnit(""); +} + void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception) { if(newOrOld) @@ -339,7 +526,7 @@ void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) throw(I m->incrRef(); _m=m; _m_by_types=(MEDCouplingUMesh *)m->deepCpy(); - MEDCouplingAutoRefCountObjectPtr da=_m_by_types->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + MEDCouplingAutoRefCountObjectPtr da=_m_by_types->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); if(!da->isIdentity()) { _num=da->invertArrayO2N2N2O(m->getNumberOfCells()); @@ -350,7 +537,7 @@ void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) throw(I } else { - if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2)) + if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh : the mode of mesh setting expects to follow the MED file numbering convention ! it is not the case !"); m->incrRef(); _m_by_types=m; @@ -441,7 +628,7 @@ void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vectorgetNumberOfCells(); std::map newfams; std::map famIdTrad; - traduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams); + TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams); for(int i=0;idecrRef(); int *w=_fam->getPointer(); @@ -519,7 +706,7 @@ DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) cons return Renumber(_num,da); } -std::vector MEDFileUMeshSplitL1::getNewFamiliesNumber(int nb, const std::map& families) +std::vector MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map& families) { int id=-1; for(std::map::const_iterator it=families.begin();it!=families.end();it++) @@ -532,7 +719,7 @@ std::vector MEDFileUMeshSplitL1::getNewFamiliesNumber(int nb, const std::ma return ret; } -void MEDFileUMeshSplitL1::traduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, +void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, std::map& famIdTrad, std::map& newfams) { std::set allfids; diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx index bf8bf89d9..c6b4a5fd5 100644 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ b/src/MEDLoader/MEDFileMeshLL.hxx @@ -23,6 +23,8 @@ #include "MEDFileBasis.hxx" #include "MEDFileMeshElt.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" #include "MEDCouplingAutoRefCountObjectPtr.hxx" extern "C" @@ -34,26 +36,37 @@ extern "C" namespace ParaMEDMEM { - class MEDCouplingUMesh; - class MEDFileMeshL2 : public RefCountObject { public: MEDFileMeshL2(); const char *getName() const { return _name.getReprForWrite(); } - const char *getDescription() const { return _description.getReprForWrite(); } + const char *getDescription() const { return _description.getReprForWrite(); } + const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); } + int getIteration() const { return _iteration; } + int getOrder() const { return _order; } + double getTime() { return _time; } + std::vector getAxisInfoOnMesh(med_idt fid, int mId, const char *mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) throw(INTERP_KERNEL::Exception); + static int GetMeshIdFromName(med_idt fid, const char *mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) throw(INTERP_KERNEL::Exception); + static double CheckMeshTimeStep(med_idt fid, const char *mname, int nstep, int dt, int it) throw(INTERP_KERNEL::Exception); + static void ReadFamiliesAndGrps(med_idt fid, const char *mname, std::map& fams, std::map >& grps); + static void WriteFamiliesAndGrps(med_idt fid, const char *mname, const std::map& fams, const std::map >& grps, int tooLongStrPol); protected: MEDFileString _name; MEDFileString _description; + MEDFileString _dt_unit; + int _iteration; + int _order; + double _time; }; class MEDFileUMeshL2 : public MEDFileMeshL2 { public: MEDFileUMeshL2(); - void loadAll(med_idt fid, int mId, const char *mName); - void loadConnectivity(med_idt fid, int mdim, const char *mName); - void loadCoords(med_idt fid, int mId, int mdim, const char *mName) throw(INTERP_KERNEL::Exception); + void loadAll(med_idt fid, int mId, const char *mName, int dt, int it); + void loadConnectivity(med_idt fid, int mdim, const char *mName, int dt, int it); + void loadCoords(med_idt fid, int mId, const std::vector& infosOnComp, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); int getNumberOfLevels() const { return _per_type_mesh.size(); } bool emptyLev(int levId) const { return _per_type_mesh[levId].empty(); } const std::vector< MEDCouplingAutoRefCountObjectPtr >& getLev(int levId) const { return _per_type_mesh[levId]; } @@ -62,10 +75,7 @@ namespace ParaMEDMEM MEDCouplingAutoRefCountObjectPtr getCoords() const { return _coords; } MEDCouplingAutoRefCountObjectPtr getCoordsFamily() const { return _fam_coords; } MEDCouplingAutoRefCountObjectPtr getCoordsNum() const { return _num_coords; } - static int getMeshIdFromName(med_idt fid, const char *mname) throw(INTERP_KERNEL::Exception); - static void readFamiliesAndGrps(med_idt fid, const char *mname, std::map& fams, std::map >& grps); - static void writeFamiliesAndGrps(med_idt fid, const char *mname, const std::map& fams, const std::map >& grps, int tooLongStrPol); - static void writeCoords(med_idt fid, const char *mname, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords); + static void WriteCoords(med_idt fid, const char *mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords); private: void sortTypes(); private: @@ -75,10 +85,19 @@ namespace ParaMEDMEM MEDCouplingAutoRefCountObjectPtr _num_coords; }; - class MEDFileUMeshL2CMesh : public MEDFileMeshL2 + class MEDFileCMeshL2 : public MEDFileMeshL2 { + public: + MEDFileCMeshL2(); + void loadAll(med_idt fid, int mId, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception); + MEDCouplingCMesh *getMesh() { return _cmesh; } + private: + static med_data_type GetDataTypeCorrespondingToSpaceId(int id) throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _cmesh; }; + class MEDFileMesh; class MEDFileUMeshSplitL1; class MEDFileUMeshPermCompute @@ -102,6 +121,9 @@ namespace ParaMEDMEM MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const char *mName, int id); MEDFileUMeshSplitL1(MEDCouplingUMesh *m); MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld); + bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; + void synchronizeTinyInfo(const MEDFileMesh& master) const; void assignMesh(MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception); bool empty() const; int getMeshDimension() const; @@ -120,8 +142,9 @@ namespace ParaMEDMEM void setFamilyArr(DataArrayInt *famArr); void setRenumArr(DataArrayInt *renumArr); // - static std::vector getNewFamiliesNumber(int nb, const std::map& families); - static void traduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, + 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, std::map& famIdTrad, std::map& newfams); static DataArrayInt *Renumber(const DataArrayInt *renum, const DataArrayInt *da); static MEDCouplingUMesh *Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds); diff --git a/src/MEDLoader/MEDFileUtilities.cxx b/src/MEDLoader/MEDFileUtilities.cxx index 222d8a860..8d019d953 100644 --- a/src/MEDLoader/MEDFileUtilities.cxx +++ b/src/MEDLoader/MEDFileUtilities.cxx @@ -22,16 +22,16 @@ #include -med_mode_acces MEDFileUtilities::TraduceWriteMode(int medloaderwritemode) throw(INTERP_KERNEL::Exception) +med_access_mode MEDFileUtilities::TraduceWriteMode(int medloaderwritemode) throw(INTERP_KERNEL::Exception) { switch(medloaderwritemode) { case 2: - return MED_CREATION; + return MED_ACC_CREAT; case 1: - return MED_LECTURE_AJOUT; + return MED_ACC_RDEXT; case 0: - return MED_LECTURE_ECRITURE; + return MED_ACC_RDWR; default: throw INTERP_KERNEL::Exception("Invalid write mode specified ! must be 0(write with no question), 1(append) or 2(creation)"); } @@ -43,7 +43,6 @@ void MEDFileUtilities::CheckMEDCode(int code, med_idt fid, const char *msg) thro { std::ostringstream oss; oss << "MEDFile has returned an error code (" << code <<") : " << msg; - MEDfermer(fid); throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -71,7 +70,7 @@ void MEDFileUtilities::CheckFileForRead(const char *fileName) throw(INTERP_KERNE throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - int fid=MEDouvrir((char *)fileName,MED_LECTURE); + AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); if(fid<0) { oss << " has been detected as unreadable by MED file : impossible to read anything !"; @@ -79,12 +78,24 @@ void MEDFileUtilities::CheckFileForRead(const char *fileName) throw(INTERP_KERNE } oss << " has been detected readable but "; int major,minor,release; - MEDversionLire(fid,&major,&minor,&release); + MEDfileNumVersionRd(fid,&major,&minor,&release); if(major<2 || (major==2 && minor<2)) { oss << "version of MED file is < 2.2 : impossible to read anything !"; - MEDfermer(fid); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDfermer(fid); +} + +MEDFileUtilities::AutoFid::AutoFid(med_idt fid):_fid(fid) +{ +} + +MEDFileUtilities::AutoFid::operator med_idt() const +{ + return _fid; +} + +MEDFileUtilities::AutoFid::~AutoFid() +{ + MEDfileClose(_fid); } diff --git a/src/MEDLoader/MEDFileUtilities.hxx b/src/MEDLoader/MEDFileUtilities.hxx index 05f3f4e1c..194bc69b7 100644 --- a/src/MEDLoader/MEDFileUtilities.hxx +++ b/src/MEDLoader/MEDFileUtilities.hxx @@ -29,9 +29,19 @@ extern "C" namespace MEDFileUtilities { - med_mode_acces TraduceWriteMode(int medloaderwritemode) throw(INTERP_KERNEL::Exception); + med_access_mode TraduceWriteMode(int medloaderwritemode) throw(INTERP_KERNEL::Exception); void CheckMEDCode(int code, med_idt fid, const char *msg) throw(INTERP_KERNEL::Exception); void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception); + + class AutoFid + { + public: + AutoFid(med_idt fid); + operator med_idt() const; + ~AutoFid(); + private: + med_idt _fid; + }; } #endif diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index 19bbc158a..41fd9721a 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -25,6 +25,7 @@ #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "InterpKernelAutoPtr.hxx" @@ -34,84 +35,94 @@ extern "C" } #include +#include #include #include #include +#include #include #include -#include -#include -med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_TRIA3, - MED_QUAD4, - MED_TRIA6, - MED_QUAD8, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_POLYGONE, - MED_POLYEDRE }; - -med_geometrie_element typmainoeud[1] = { MED_NONE }; - -INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_POINT1, - INTERP_KERNEL::NORM_SEG2, - INTERP_KERNEL::NORM_SEG3, - INTERP_KERNEL::NORM_TRI3, - INTERP_KERNEL::NORM_QUAD4, - INTERP_KERNEL::NORM_TRI6, - INTERP_KERNEL::NORM_QUAD8, - INTERP_KERNEL::NORM_TETRA4, - INTERP_KERNEL::NORM_PYRA5, - INTERP_KERNEL::NORM_PENTA6, - INTERP_KERNEL::NORM_HEXA8, - INTERP_KERNEL::NORM_TETRA10, - INTERP_KERNEL::NORM_PYRA13, - INTERP_KERNEL::NORM_PENTA15, - INTERP_KERNEL::NORM_HEXA20, - INTERP_KERNEL::NORM_POLYGON, - INTERP_KERNEL::NORM_POLYHED }; - -med_geometrie_element typmai3[32] = { MED_POINT1,//0 - MED_SEG2,//1 - MED_SEG3,//2 - MED_TRIA3,//3 - MED_QUAD4,//4 - MED_POLYGONE,//5 - MED_TRIA6,//6 - MED_NONE,//7 - MED_QUAD8,//8 - MED_NONE,//9 - MED_NONE,//10 - MED_NONE,//11 - MED_NONE,//12 - MED_NONE,//13 - MED_TETRA4,//14 - MED_PYRA5,//15 - MED_PENTA6,//16 - MED_NONE,//17 - MED_HEXA8,//18 - MED_NONE,//19 - MED_TETRA10,//20 - MED_NONE,//21 - MED_NONE,//22 - MED_PYRA13,//23 - MED_NONE,//24 - MED_PENTA15,//25 - MED_NONE,//26 - MED_NONE,//27 - MED_NONE,//28 - MED_NONE,//29 - MED_HEXA20,//30 - MED_POLYEDRE//31 +med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1, + MED_SEG2, + MED_SEG3, + MED_SEG4, + MED_TRIA3, + MED_QUAD4, + MED_TRIA6, + MED_TRIA7, + MED_QUAD8, + MED_QUAD9, + MED_TETRA4, + MED_PYRA5, + MED_PENTA6, + MED_HEXA8, + MED_OCTA12, + MED_TETRA10, + MED_PYRA13, + MED_PENTA15, + MED_HEXA20, + MED_HEXA27, + MED_POLYGON, + MED_POLYHEDRON }; + +med_geometry_type typmainoeud[1] = { MED_NONE }; + +INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1, + INTERP_KERNEL::NORM_SEG2, + INTERP_KERNEL::NORM_SEG3, + INTERP_KERNEL::NORM_ERROR,//SEG4 + INTERP_KERNEL::NORM_TRI3, + INTERP_KERNEL::NORM_QUAD4, + INTERP_KERNEL::NORM_TRI6, + INTERP_KERNEL::NORM_ERROR,//TRI7 + INTERP_KERNEL::NORM_QUAD8, + INTERP_KERNEL::NORM_ERROR,//QUAD9 + 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_ERROR,//HEXA27 + INTERP_KERNEL::NORM_POLYGON, + INTERP_KERNEL::NORM_POLYHED }; + +med_geometry_type typmai3[32] = { MED_POINT1,//0 + MED_SEG2,//1 + MED_SEG3,//2 + MED_TRIA3,//3 + MED_QUAD4,//4 + MED_POLYGON,//5 + MED_TRIA6,//6 + MED_NONE,//7 + MED_QUAD8,//8 + MED_NONE,//9 + MED_NONE,//10 + MED_NONE,//11 + MED_NONE,//12 + MED_NONE,//13 + MED_TETRA4,//14 + MED_PYRA5,//15 + MED_PENTA6,//16 + MED_NONE,//17 + MED_HEXA8,//18 + MED_NONE,//19 + MED_TETRA10,//20 + MED_NONE,//21 + MED_OCTA12,//22 + MED_PYRA13,//23 + MED_NONE,//24 + MED_PENTA15,//25 + MED_NONE,//26 + MED_NONE,//27 + MED_NONE,//28 + MED_NONE,//29 + MED_HEXA20,//30 + MED_POLYHEDRON//31 }; double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; @@ -151,9 +162,9 @@ namespace MEDLoaderNS std::vector getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams); std::vector getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps); med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception); - void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity); + void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities); - void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn); + void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn, std::string& desc); int buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, std::vector& fam4MEDFile, std::vector& renumber); @@ -174,10 +185,10 @@ namespace MEDLoaderNS int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, - ParaMEDMEM::TypeOfField typeOfOutField); + ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception); ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *renumCell, const ParaMEDMEM::MEDCouplingUMesh *mesh, const std::vector& infos, const char *fieldName, int iteration, int order, double time, - std::list& fieldPerCellType); + std::list& fieldPerCellType) throw(INTERP_KERNEL::Exception); med_idt appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt); void appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); void appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds); @@ -261,15 +272,23 @@ void MEDLoader::MEDFieldDoublePerCellType::releaseArray() std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) { - med_maillage type_maillage; - char maillage_description[MED_TAILLE_DESC+1]; - med_int dim; - char nommaa[MED_TAILLE_NOM+1]; - med_int n=MEDnMaa(fid); + med_mesh_type type_maillage; + char maillage_description[MED_COMMENT_SIZE+1]; + char dtunit[MED_COMMENT_SIZE+1]; + med_int space_dim; + med_int mesh_dim; + char nommaa[MED_NAME_SIZE+1]; + med_axis_type axistype; + med_sorting_type stype; + med_int n=MEDnMesh(fid); std::vector ret(n); for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + int nstep; + MEDmeshInfo(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit); std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); ret[i]=cur; } @@ -278,28 +297,34 @@ std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f) { - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - char locName[MED_TAILLE_NOM+1]; - int nloc=MEDnGauss(fid); - med_geometrie_element typeGeo; + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + char locName[MED_NAME_SIZE+1]; + int nloc=MEDnLocalization(fid); + med_geometry_type typeGeo; for(std::list::const_iterator iter=data.begin();iter!=data.end();iter++) { const std::string& loc=(*iter).getLocName(); int idLoc=1; int nbOfGaussPt=-1; + med_int spaceDim; for(;idLoc<=nloc;idLoc++) { - MEDgaussInfo(fid,idLoc,locName,&typeGeo,&nbOfGaussPt); + char geointerpname[MED_NAME_SIZE+1]=""; + char ipointstructmeshname[MED_NAME_SIZE+1]=""; + med_int nsectionmeshcell; + med_geometry_type sectiongeotype; + MEDlocalizationInfo(fid,idLoc,locName,&typeGeo,&spaceDim,&nbOfGaussPt, geointerpname, ipointstructmeshname, &nsectionmeshcell, + §iongeotype); if(loc==locName) break; } int dim=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension(); int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes(); std::vector refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt); - MEDgaussLire(fid,(med_float *)&refcoo[0],(med_float *)&gscoo[0],(med_float *)&w[0],MED_FULL_INTERLACE,(char *)(*iter).getLocName().c_str()); + MEDlocalizationRd(fid,(*iter).getLocName().c_str(),MED_FULL_INTERLACE,&refcoo[0],&gscoo[0],&w[0]); f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w); } - MEDfermer(fid); + MEDfileClose(fid); } void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception) @@ -310,9 +335,9 @@ void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exce std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -320,146 +345,114 @@ std::vector MEDLoader::GetMeshNamesOnField(const char *fileName, co { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); // - med_type_champ typcha; - //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; - med_float dt=0.0; - med_booleen local; - //char pflname[MED_TAILLE_NOM+1]=""; - //char locname[MED_TAILLE_NOM+1]=""; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) - { - bool found=false; - for(int j=0;j MEDLoader::GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nfam=MEDnFam(fid,(char *)meshName); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName); std::vector ret(nfam); - char nomfam[MED_TAILLE_NOM+1]; + char nomfam[MED_NAME_SIZE+1]; med_int numfam; for(int i=0;i attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); ret[i]=cur; - delete [] attdes; - delete [] gro; - delete [] attide; - delete [] attval; } - MEDfermer(fid); + MEDfileClose(fid); return ret; } + std::vector MEDLoader::GetMeshFamiliesNamesOnGroup(const char *fileName, const char *meshName, const char *grpName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nfam=MEDnFam(fid,(char *)meshName); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName); std::vector ret; - char nomfam[MED_TAILLE_NOM+1]; + char nomfam[MED_NAME_SIZE+1]; med_int numfam; for(int i=0;i attide=new int[natt]; - INTERP_KERNEL::AutoPtr attval=new int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_TAILLE_DESC*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_TAILLE_LNOM*ngro+1]; - MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro); + int ngro=MEDnFamilyGroup(fid,meshName,i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName,i+1); + INTERP_KERNEL::AutoPtr attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); for(int j=0;j MEDLoader::GetMeshGroupsNamesOnFamily(const char *fileName, const char *meshName, const char *famName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nfam=MEDnFam(fid,(char *)meshName); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName); std::vector ret; - char nomfam[MED_TAILLE_NOM+1]; + char nomfam[MED_NAME_SIZE+1]; med_int numfam; bool found=false; for(int i=0;i attide=new int[natt]; - INTERP_KERNEL::AutoPtr attval=new int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_TAILLE_DESC*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_TAILLE_LNOM*ngro+1]; - MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro); + int ngro=MEDnFamilyGroup(fid,meshName,i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName,i+1); + INTERP_KERNEL::AutoPtr attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); found=(cur==famName); if(found) for(int j=0;j MEDLoader::GetMeshGroupsNamesOnFamily(const char *fileN } return ret; } + std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nfam=MEDnFam(fid,(char *)meshName); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName); std::vector ret; - char nomfam[MED_TAILLE_NOM+1]; + char nomfam[MED_NAME_SIZE+1]; med_int numfam; for(int i=0;i attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName,i+1,nomfam,attide,attval,attdes,&numfam,gro); for(int j=0;j MEDLoader::GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception) +std::vector MEDLoader::GetTypesOfField(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; + med_field_type typcha; //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - //char pflname[MED_TAILLE_NOM+1]=""; - //char locname[MED_TAILLE_NOM+1]=""; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + if(curMeshName==meshName) { - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); - if(nbPdt>0) + if(curFieldName==fieldName) { - bool found=false; - for(int i=0;i0) { - MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); - if(curMeshName==meshName) + bool found=false; + for(int i=0;i0) + { + ret.push_back(ON_NODES); + found=true; + } } } - } - bool found=false; - for(int j=0;j0) + bool found=false; + for(int j=0;j0) { - found=true; - ret.push_back(ON_CELLS); + MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); + med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi); + if(nbOfVal>0) + { + found=true; + ret.push_back(ON_CELLS); + } } } } } } delete [] maa_ass; - delete [] dt_unit; delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -573,22 +565,23 @@ std::vector MEDLoader::GetAllFieldNames(const char *fileName) throw { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); - med_type_champ typcha; + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + med_field_type typcha; for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + med_bool localmesh; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); ret.push_back(std::string(nomcha)); - delete [] nomcha; - delete [] comp; - delete [] unit; } - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -596,66 +589,31 @@ std::vector MEDLoader::GetAllFieldNamesOnMesh(const char *fileName, { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; - med_float dt=0.0; - med_booleen local; - //char pflname[MED_TAILLE_NOM+1]=""; - //char locname[MED_TAILLE_NOM+1]=""; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + med_field_type typcha; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + med_bool localmesh; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); // - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); - bool found=false; - if(nbPdt>0) - { - for(int i=0;i0) - { - MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); - if(curMeshName==meshName) - { - found=true; - ret.push_back(curFieldName); - } - } - } + if(curMeshName==meshName) + ret.push_back(curFieldName); } delete [] maa_ass; - delete [] dt_unit; delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -677,50 +635,50 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; + med_field_type typcha; //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - //char pflname[MED_TAILLE_NOM+1]=""; - //char locname[MED_TAILLE_NOM+1]=""; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + med_int nbPdt; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + int profilesize,nbi; + if(curMeshName==meshName) { - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]); - if(nbPdt>0) + bool found=false; + for(int j=0;j0) { - found=true; - ret.push_back(curFieldName); + MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); + med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi); + if(nbOfVal>0) + { + found=true; + ret.push_back(curFieldName); + } } } } } - delete [] maa_ass; - delete [] dt_unit; - delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -728,44 +686,43 @@ std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName { CheckFileForRead(fileName); std::vector ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; // - med_type_champ typcha; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_field_type typcha; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); bool found=false; - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); if(nbPdt>0) { - MEDpasdetempsInfo(fid,nomcha,MED_NOEUD,MED_NONE,1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); - if(curMeshName==meshName) + int profilesize,nbi; + MEDfieldComputingStepInfo(fid,nomcha,1,&numdt,&numo,&dt); + med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi); + if(curMeshName==meshName && nbOfVal>0) { found=true; ret.push_back(curFieldName); } } } - delete [] maa_ass; - delete [] dt_unit; - delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -773,111 +730,98 @@ std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIter { CheckFileForRead(fileName); std::string meshNameCpp(meshName); - std::vector< std::pair< std::pair, double> > ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + std::vector< std::pair< std::pair, double > > ret; + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_field_type typcha; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { bool found=false; - for(int j=0;j0) { found=true; ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt)); } } } - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); for(int k=0;k0) + { + found=true; + ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt)); + } } } } - delete [] maa_ass; - delete [] dt_unit; - delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } double MEDLoader::GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { CheckFileForRead(fileName); - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_field_type typcha; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + med_bool local; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); // bool found=false; bool found2=false; double ret=std::numeric_limits::max(); for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { found=true; - for(int j=0;j > MEDLoader::GetCellFieldIterations(const char * CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_field_type typcha; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { bool found=false; - for(int j=0;j0) { found=true; ret.push_back(std::make_pair(numdt,numo)); @@ -959,10 +902,7 @@ std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char * } } } - delete [] maa_ass; - delete [] dt_unit; - delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -971,45 +911,44 @@ std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char * CheckFileForRead(fileName); std::string meshNameCpp(meshName); std::vector< std::pair > ret; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - med_int ngauss=0; - med_int numdt=0,numo=0,nbrefmaa; + med_field_type typcha; + med_int numdt=0,numo=0; med_float dt=0.0; - med_booleen local; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); for(int k=0;k0) { ret.push_back(std::make_pair(numdt,numo)); } } } } - delete [] maa_ass; - delete [] dt_unit; - delete [] nomcha; - MEDfermer(fid); + MEDfileClose(fid); return ret; } @@ -1024,170 +963,154 @@ void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char double& time, std::vector& infos) { time=0.; - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nbFields=MEDnChamp(fid,0); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); // - med_type_champ typcha; - char nomcha[MED_TAILLE_NOM+1]=""; - char pflname [MED_TAILLE_NOM+1]=""; - char locname [MED_TAILLE_NOM+1]=""; - std::map tabEnt; - std::map tabType; + med_field_type typcha; + char nomcha[MED_NAME_SIZE+1]=""; + char pflname [MED_NAME_SIZE+1]=""; + char locname [MED_NAME_SIZE+1]=""; + std::map tabEnt; + std::map tabType; std::map tabTypeLgth; - tabEnt[ON_CELLS]=MED_MAILLE; + med_bool localmesh; + tabEnt[ON_CELLS]=MED_CELL; tabType[ON_CELLS]=typmai; - tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2; - tabEnt[ON_NODES]=MED_NOEUD; + tabTypeLgth[ON_CELLS]=MED_N_CELL_FIXED_GEO; + tabEnt[ON_NODES]=MED_NODE; tabType[ON_NODES]=typmainoeud; tabTypeLgth[ON_NODES]=1; - tabEnt[ON_GAUSS_PT]=MED_MAILLE; + tabEnt[ON_GAUSS_PT]=MED_CELL; tabType[ON_GAUSS_PT]=typmai; - tabTypeLgth[ON_GAUSS_PT]=MED_NBR_GEOMETRIE_MAILLE+2; - tabEnt[ON_GAUSS_NE]=MED_MAILLE; + tabTypeLgth[ON_GAUSS_PT]=MED_N_CELL_FIXED_GEO; + tabEnt[ON_GAUSS_NE]=MED_NODE_ELEMENT; tabType[ON_GAUSS_NE]=typmai; - tabTypeLgth[ON_GAUSS_NE]=MED_NBR_GEOMETRIE_MAILLE+2; + tabTypeLgth[ON_GAUSS_NE]=MED_N_CELL_FIXED_GEO; // for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_int nbPdt; + MEDfieldInfo(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + if(curMeshName!=meshName) + { + MEDfileClose(fid); + throw INTERP_KERNEL::Exception("Invalid meshname on field !"); + } + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); if(curFieldName==fieldName) { infos.resize(ncomp); for(int i=0;i0) { @@ -1267,7 +1207,7 @@ int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName poss.insert(curDim); } } - MEDfermer(fid); + MEDfileClose(fid); if(!poss.empty()) { ret=*poss.rbegin(); @@ -1279,38 +1219,49 @@ int MEDLoaderNS::readUMeshDimFromFile(const char *fileName, const char *meshName return ret; } -void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn) +void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn, std::string& description) { - char nommaa[MED_TAILLE_NOM+1]; - char maillage_description[MED_TAILLE_DESC+1]; - med_maillage type_maillage; + char nommaa[MED_NAME_SIZE+1]; + char maillage_description[MED_COMMENT_SIZE+1]; + med_mesh_type type_maillage; med_int Mdim; - MEDmaaInfo(fid,meshId,nommaa,&Mdim,&type_maillage,maillage_description); - med_int edim=MEDdimEspaceLire(fid,nommaa); - int spaceDim=std::max((int)Mdim,(int)edim); - int nCoords=MEDnEntMaa(fid,nommaa,MED_COOR,MED_NOEUD,(med_geometrie_element)0,(med_connectivite)0); + med_int Sdim; + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_sorting_type sortingType; + med_int nstep; + med_axis_type axisType; + med_int numdt,numit; + med_float dt; + med_bool changement,transformation; + // endlimitation + Sdim=MEDmeshnAxis(fid,1); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(Sdim*MED_SNAME_SIZE); + MEDmeshInfo(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,comp,unit); + description=MEDLoaderBase::buildStringFromFortran(maillage_description,sizeof(maillage_description)); + MEDmeshComputationStepInfo(fid,nommaa,1,&numdt,&numit,&dt); + int spaceDim=std::max((int)Mdim,(int)Sdim); + int nCoords=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation); + // limitation + if(nstep!=1) + { + throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); + } coords=DataArrayDouble::New(); coords->alloc(nCoords,spaceDim); double *coordsPtr=coords->getPointer(); - med_repere repere; - char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - MEDcoordLire(fid,nommaa,spaceDim,coordsPtr,MED_FULL_INTERLACE,MED_ALL,NULL,0,&repere,comp,unit); + MEDmeshNodeCoordinateRd(fid,nommaa,numdt,numit,MED_FULL_INTERLACE,coordsPtr); for(int i=0;isetInfoOnComponent(i,info.c_str()); } - delete [] comp; - delete [] unit; - med_booleen inoele, inuele; - for(int i=0;i0) @@ -1318,54 +1269,73 @@ void MEDLoaderNS::readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayD int *connTab=new int[(curMedType%100)*curNbOfElem]; int *fam=new int[curNbOfElem]; MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,0,fam,curNbOfElem,-1); - int *tmp=new int[curNbOfElem]; - char *noms=new char[MED_TAILLE_PNOM*curNbOfElem+1]; - MEDelementsLire(fid,nommaa,Mdim,connTab,MED_FULL_INTERLACE,noms,&inoele,tmp,&inuele,fam,curNbOfElem,whichEntity,curMedType,MED_NOD); - delete [] tmp; + char *noms=new char[MED_SNAME_SIZE*curNbOfElem+1]; + med_bool withname=MED_FALSE,withnumber=MED_FALSE,withfam=MED_FALSE; + int *globArr=new int[curNbOfElem]; + MEDmeshElementRd(fid,nommaa,numdt,numit,whichEntity,curMedType,MED_NODAL,MED_FULL_INTERLACE,connTab,&withname,noms,&withnumber,globArr,&withfam,fam); + if(!withfam) + std::fill(fam,fam+curNbOfElem,0); delete [] noms; //trying to read global numbering - int *globArr=new int[curNbOfElem]; - if(MEDnumLire(fid,nommaa,globArr,curNbOfElem,whichEntity,curMedType)==0) + if(withnumber) elem.setGlobal(globArr); else delete [] globArr; + //limitation manage withfam==false conn.push_back(elem); } } int curNbOfPolyElem; - int curNbOfPolyElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYGONE,MED_NOD); - int curNbOfPolyElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,MED_POLYGONE,MED_NOD); - med_entite_maillage whichPolyEntity; + int curNbOfPolyElemM=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1; + int curNbOfPolyElemF=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1;//limitation + med_entity_type whichPolyEntity; MEDLoaderNS::dispatchElems(curNbOfPolyElemM,curNbOfPolyElemF,curNbOfPolyElem,whichPolyEntity); if(curNbOfPolyElem>0) { - med_int arraySize; - MEDpolygoneInfo(fid,nommaa,whichPolyEntity,MED_NOD,&arraySize); + med_int arraySize=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation); int *index=new int[curNbOfPolyElem+1]; int *locConn=new int[arraySize]; int *fam=new int[curNbOfPolyElem]; int *globArr=new int[curNbOfPolyElem]; MEDLoader::MEDConnOfOneElemType elem(INTERP_KERNEL::NORM_POLYGON,locConn,index,fam,curNbOfPolyElem,arraySize); - MEDpolygoneConnLire(fid,nommaa,index,curNbOfPolyElem+1,locConn,whichPolyEntity,MED_NOD); - MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,whichPolyEntity,MED_POLYGONE); - if(MEDnumLire(fid,nommaa,globArr,curNbOfPolyElem,whichPolyEntity,MED_POLYGONE)==0) - elem.setGlobal(globArr); + MEDmeshPolygonRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,locConn); + if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,fam)!=0) + std::fill(fam,fam+curNbOfPolyElem,0); + } + else + std::fill(fam,fam+curNbOfPolyElem,0); + if(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYGON,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYGON,globArr)==0) + elem.setGlobal(globArr); + else + delete [] globArr; + } else delete [] globArr; conn.push_back(elem); } - curNbOfPolyElem=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,MED_POLYEDRE,MED_NOD); + curNbOfPolyElem=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1; if(curNbOfPolyElem>0) { med_int indexFaceLgth,connFaceLgth; - MEDpolyedreInfo(fid,nommaa,MED_NOD,&indexFaceLgth,&connFaceLgth); - int *index=new int[curNbOfPolyElem+1]; - int *indexFace=new int[indexFaceLgth]; - int *locConn=new int[connFaceLgth]; + indexFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation); + connFaceLgth=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,MED_POLYHEDRON,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation); + INTERP_KERNEL::AutoPtr index=new int[curNbOfPolyElem+1]; + INTERP_KERNEL::AutoPtr indexFace=new int[indexFaceLgth]; + INTERP_KERNEL::AutoPtr locConn=new int[connFaceLgth]; int *fam=new int[curNbOfPolyElem]; int *globArr=new int[curNbOfPolyElem]; - MEDpolyedreConnLire(fid,nommaa,index,curNbOfPolyElem+1,indexFace,indexFaceLgth,locConn,MED_NOD); - MEDfamLire(fid,nommaa,fam,curNbOfPolyElem,MED_MAILLE,MED_POLYEDRE); + MEDmeshPolyhedronRd(fid,nommaa,numdt,numit,MED_CELL,MED_NODAL,index,indexFace,locConn); + if(MEDmeshnEntity(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(MEDmeshEntityFamilyNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,fam)!=0) + std::fill(fam,fam+curNbOfPolyElem,0); + } + else + std::fill(fam,fam+curNbOfPolyElem,0); int arraySize=connFaceLgth; for(int i=0;i0) + { + if(MEDmeshEntityNumberRd(fid,nommaa,numdt,numit,whichPolyEntity,MED_POLYHEDRON,globArr)==0) + elem.setGlobal(globArr); + else + delete [] globArr; + } else delete [] globArr; conn.push_back(elem); @@ -1780,20 +1752,22 @@ MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const if(meshDimRelToMax>0) throw INTERP_KERNEL::Exception("meshDimRelToMax must be <=0 !"); //Extraction data from MED file. - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); std::string trueMeshName; med_int mid=getIdFromMeshName(fid,meshName,trueMeshName); DataArrayDouble *coords=0; std::list conn; - readUMeshDataInMedFile(fid,mid,coords,conn); + std::string descr; + readUMeshDataInMedFile(fid,mid,coords,conn,descr); meshDimExtract=MEDLoaderNS::calculateHighestMeshDim(conn); meshDimExtract=meshDimExtract+meshDimRelToMax; MEDLoaderNS::keepSpecifiedMeshDim(conn,meshDimExtract); MEDLoaderNS::keepTypes(conn,typesToKeep); - MEDfermer(fid); + MEDfileClose(fid); //Put data in returned data structure. MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); ret->setName(trueMeshName.c_str()); + ret->setDescription(descr.c_str()); ret->setMeshDimension(meshDimExtract); // ret->setCoords(coords); @@ -1813,10 +1787,20 @@ MEDCouplingUMesh *MEDLoaderNS::readUMeshFromFileLev1(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *cellRenum, const ParaMEDMEM::MEDCouplingUMesh *mesh, const std::vector& infos, const char *fieldName, int iteration, int order, double time, - std::list& fieldPerCellType) + std::list& fieldPerCellType) throw(INTERP_KERNEL::Exception) { if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) MEDLoaderNS::keepSpecifiedMeshDim(fieldPerCellType,meshDim); + if(fieldPerCellType.empty()) + { + std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << mesh->getName(); + oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl; + if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) + oss << "Request for cell field, maybe it is an ON_NODES field ?"; + else + oss << "Request for a node field, maybe it is an ON_CELLS field ?"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } //for profiles ParaMEDMEM::MEDCouplingUMesh *newMesh=0; std::string mName(mesh->getName()); @@ -1831,9 +1815,9 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char if(typeOfOutField==ON_CELLS) { if(newMesh) - mesh2=newMesh->keepSpecifiedCells((*iter).getType(),ci); + mesh2=newMesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size()); else - mesh2=mesh->keepSpecifiedCells((*iter).getType(),ci); + mesh2=mesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size()); } else if(typeOfOutField==ON_NODES) { @@ -1854,7 +1838,7 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char mesh2=dynamic_cast(mesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2)); // int nnodes=mesh2->getNumberOfNodes(); - DataArrayInt *da3=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr da3=DataArrayInt::New(); const int *da2Ptr=da2->getConstPointer(); da3->alloc(nnodes,1); int *da3Ptr=da3->getPointer(); @@ -1865,7 +1849,6 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char da3Ptr[val]=i; } mesh2->renumberNodes(da3->getConstPointer(),nnodes); - da3->decrRef(); } else { @@ -1911,7 +1894,7 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char } ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, - ParaMEDMEM::TypeOfField typeOfOutField) + ParaMEDMEM::TypeOfField typeOfOutField) throw(INTERP_KERNEL::Exception) { std::list fieldPerCellType; double time; @@ -1924,11 +1907,20 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev1(const char typesToKeep.push_back((*iter).getType()); unsigned meshDim; int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); + if(fieldPerCellType.empty()) + { + std::ostringstream oss; oss << "Error on reading file \"" << fileName << "\" meshName=\"" << meshName << "\" meshDimRelToMax=" << meshDimRelToMax; + oss << std::endl << "FieldName=\"" << fieldName << "\" (iteration=" << iteration << ",order=" << order << ")" << std::endl; + if(typeOfOutField==ON_CELLS || typeOfOutField==ON_GAUSS_PT || typeOfOutField==ON_GAUSS_NE) + oss << "Request for cell field, maybe it is a node instead or by changing meshDimRelToMax ?"; + else + oss << "Request for a node field, maybe it is a cell field instead ?"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr mesh=readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); ParaMEDMEM::MEDCouplingFieldDouble *ret=readFieldDoubleLev2(fileName,typeOfOutField,meshDim,cellRenum,mesh,infos,fieldName,iteration,order,time,fieldPerCellType); if(cellRenum) mesh->renumberCells(cellRenum,true); - mesh->decrRef(); //clean-up delete [] cellRenum; releaseMEDFileCoreFrmt(fieldPerCellType); @@ -2049,7 +2041,7 @@ std::vector MEDLoader::ReadFieldsOnSameMes typesToKeep.push_back((*iter).getType()); unsigned meshDim; int *cellRenum; - ParaMEDMEM::MEDCouplingUMesh *m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); + MEDCouplingAutoRefCountObjectPtr m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); ret[0]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[0].first,its[0].second,time,fieldPerCellType); if(cellRenum) m1->renumberCells(cellRenum,true); @@ -2070,7 +2062,6 @@ std::vector MEDLoader::ReadFieldsOnSameMes //clean-up MEDLoaderNS::releaseMEDFileCoreFrmt(fieldPerCellType); } - m1->decrRef(); delete [] cellRenum; return ret; } @@ -2125,11 +2116,11 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *file */ void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering) { - med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE); + med_idt fid=MEDfileOpen(fileName,forceFromScratch?MED_ACC_CREAT:MED_ACC_RDWR); std::string meshName(mesh[0]->getName()); if(meshName=="") { - MEDfermer(fid); + MEDfileClose(fid); throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); } isRenumbering=false; @@ -2139,25 +2130,36 @@ void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector allTypes; for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) { - isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO); isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0); conn.push_back((*iter)->getNodalConnectivity()); connIndex.push_back((*iter)->getNodalConnectivityIndex()); const std::set& curTypes=(*iter)->getAllTypes(); allTypes.insert(curTypes.begin(),curTypes.end()); } - char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - char *desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC); - MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_DESC,desc,MEDLoader::_TOO_LONG_STR); + INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(mesh[0]->getDescription(),MED_COMMENT_SIZE,desc,MEDLoader::_TOO_LONG_STR); const int spaceDim=mesh[0]->getSpaceDimension(); - MEDmaaCr(fid,maa,spaceDim,MED_NON_STRUCTURE,desc); - MEDdimEspaceCr(fid,maa,spaceDim); + const int meshDim=mesh[0]->getMeshDimension(); + const DataArrayDouble *arr=mesh[0]->getCoords(); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + for(int i=0;igetInfoOnComponent(i); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_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,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDmeshCr(fid,maa,spaceDim,meshDim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit); for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) { - for(int i=0;i fam; std::vector renumber; int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber); - if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) - MEDconnEcr(fid,maa,(*iter)->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + if(curMedType!=MED_POLYGON && curMedType!=MED_POLYHEDRON) + MEDmeshElementConnectivityWr(fid,maa,-1,-1,0.,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfElt,&medConn[0]); else { - if(curMedType==MED_POLYGONE) - MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); - if(curMedType==MED_POLYEDRE) + if(curMedType==MED_POLYGON) + MEDmeshPolygonWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex.size(),&medConnIndex[0],&medConn[0]); + if(curMedType==MED_POLYHEDRON) { - MEDpolyedreConnEcr(fid,maa,&medConnIndex2[0],medConnIndex2.size(),&medConnIndex[0],medConnIndex.size(), - &medConn[0],MED_NOD); + MEDmeshPolyhedronWr(fid,maa,-1,-1,0.,MED_CELL,MED_NODAL,medConnIndex2.size(),&medConnIndex2[0],medConnIndex.size(),&medConnIndex[0], + &medConn[0]); } } if(isFamilies) - MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType); + MEDmeshEntityFamilyNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&fam[0]); if(isRenumbering) - MEDnumEcr(fid,maa,&renumber[0],nbOfElt,MED_MAILLE,curMedType); + MEDmeshEntityNumberWr(fid,maa,-1,-1,MED_CELL,curMedType,nbOfElt,&renumber[0]); } } } - char familyName[MED_TAILLE_NOM+1]; - std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); + char familyName[MED_NAME_SIZE+1]; + std::fill(familyName,familyName+MED_NAME_SIZE+1,'\0'); const char DftFamilyName[]="DftFamily"; std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); - MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); - DataArrayDouble *arr=mesh[0]->getCoords(); - char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); - for(int i=0;igetInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDcoordEcr(fid,maa,spaceDim,arr->getPointer(),MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),MED_CART,comp,unit); - delete [] comp; - delete [] unit; - delete [] maa; - delete [] desc; - MEDfermer(fid); + MEDfamilyCr(fid,maa,familyName,0,0,0); + + MEDmeshNodeCoordinateWr(fid,maa,-1,-1,0.,MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),arr->getPointer()); + MEDfileClose(fid); } /*! @@ -2217,16 +2205,16 @@ void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector& meshes, bool forceFromScratch) { std::string meshNameCpp(meshName); - char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(meshName,MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); + INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(meshName,MED_NAME_SIZE,maa,MEDLoader::_TOO_LONG_STR); if(meshNameCpp=="") throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !"); std::vector< DataArrayInt * > corr; - MEDCouplingUMesh *m=ParaMEDMEM::MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + MEDCouplingAutoRefCountObjectPtr m=ParaMEDMEM::MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); m->setName(meshName); std::vector< std::vector > fidsOfGroups; std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end()); - DataArrayInt *arr2=DataArrayInt::MakePartition(corr2,m->getNumberOfCells(),fidsOfGroups); + MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::MakePartition(corr2,m->getNumberOfCells(),fidsOfGroups); for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++) (*it)->decrRef(); bool isRenumbering; @@ -2249,25 +2237,19 @@ void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char gidsOfFamilies[fid].push_back(gid); } fid=0; - med_idt fid2=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE); + med_idt fid2=MEDfileOpen(fileName,MED_ACC_RDWR); for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) { int ngro=gidsOfFamilies[fid].size(); - char *groName=MEDLoaderBase::buildEmptyString(MED_TAILLE_LNOM*ngro); + INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); for(int i=0;igetName(),MED_TAILLE_LNOM-1,groName+i*MED_TAILLE_LNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_LNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(meshes[gidsOfFamilies[fid][i]]->getName(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,MEDLoader::_TOO_LONG_STR);//MED_LNAME_SIZE-1 to avoid to write '\0' on next compo std::ostringstream oss; oss << "Family_" << *it; - char *famName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,famName,MEDLoader::_TOO_LONG_STR); - MEDfamCr(fid2,maa,famName,*it,0,0,0,0,groName,ngro); - delete [] famName; - delete [] groName; + INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,famName,MEDLoader::_TOO_LONG_STR); + MEDfamilyCr(fid2,maa,famName,*it,ngro,groName); } - MEDfermer(fid2); - // end families creation - delete [] maa; - arr2->decrRef(); - m->decrRef(); + MEDfileClose(fid2); } /*! @@ -2278,24 +2260,19 @@ void MEDLoaderNS::appendNodeProfileField(const char *fileName, const ParaMEDMEM: { med_int numdt,numo; med_float dt; - char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); + INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); int nbOfNodes=f->getMesh()->getNumberOfNodes(); const double *pt=f->getArray()->getConstPointer(); - int *profile=new int[nbOfNodes]; + INTERP_KERNEL::AutoPtr profile=new int[nbOfNodes]; std::ostringstream oss; oss << "Pfln" << f->getName(); - char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR); - std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,profile,std::bind2nd(std::plus(),1)); - MEDprofilEcr(fid,profile,nbOfNodes,profileName); - delete [] profile; - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfNodes, - (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_NOEUD, - MED_NONE,numdt,(char *)"",dt,numo); - delete [] profileName; - delete [] nommaa; - MEDfermer(fid); + INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); + std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,(int *)profile,std::bind2nd(std::plus(),1)); + MEDprofileWr(fid,profileName,nbOfNodes,profile); + MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE,profileName,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfNodes,(const unsigned char*)pt); + MEDfileClose(fid); } /*! @@ -2314,24 +2291,21 @@ void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM: int number=0; for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) { - char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); - char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); + INTERP_KERNEL::AutoPtr profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++; - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR); const std::vector& ids=(*iter).getCellIdPerType(); int *profile=new int [ids.size()]; std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus(),1)); - MEDprofilEcr(fid,profile,ids.size(),profileName); + MEDprofileWr(fid,profileName,ids.size(),profile); delete [] profile; - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(), - (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_MAILLE, - typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); - delete [] profileName; - delete [] nommaa; + MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,profileName, + MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt); pt+=(*iter).getNbOfTuple()*nbComp; } - MEDfermer(fid); + MEDfileClose(fid); } /*! @@ -2339,23 +2313,29 @@ void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM: */ med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt) { - med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE); + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDWR); int nbComp=f->getNumberOfComponents(); - char *comp=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM); - char *unit=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); for(int i=0;igetArray()->getInfoOnComponent(i); std::string c,u; MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR); - MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR); - } - MEDchampCr(fid,(char *)f->getName(),MED_FLOAT64,comp,unit,nbComp); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,MEDLoader::_TOO_LONG_STR); + } + INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr maaname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr fname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fname,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,maaname,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(f->getTimeUnit(),MED_SNAME_SIZE,dt_unit,MEDLoader::_TOO_LONG_STR); + MEDfieldCr(fid,fname,MED_FLOAT64,nbComp,comp,unit,dt_unit,maaname); ParaMEDMEM::TypeOfTimeDiscretization td=f->getTimeDiscretization(); if(td==ParaMEDMEM::NO_TIME) { - numdt=MED_NOPDT; numo=MED_NONOR; dt=0.0; + numdt=MED_NO_DT; numo=MED_NO_IT; dt=0.0; } else if(td==ParaMEDMEM::ONE_TIME) { @@ -2364,8 +2344,6 @@ med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM numdt=(med_int)tmp1; numo=(med_int)tmp2; dt=(med_float)tmp0; } - delete [] comp; - delete [] unit; return fid; } @@ -2379,21 +2357,20 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME const MEDCouplingUMesh *meshC=dynamic_cast(mesh); if(!meshC) throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); - bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO); if(renum) { ParaMEDMEM::MEDCouplingFieldDouble *f3=f2->clone(true); - DataArrayInt *da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + MEDCouplingAutoRefCountObjectPtr da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); f3->renumberCells(da->getConstPointer(),false); - da->decrRef(); f=f3; } //end renumbering int nbComp=f->getNumberOfComponents(); med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); const double *pt=f->getArray()->getConstPointer(); - char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); - MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); + INTERP_KERNEL::AutoPtr nommaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_NAME_SIZE,nommaa,MEDLoader::_TOO_LONG_STR); switch(f->getTypeOfField()) { case ParaMEDMEM::ON_CELLS: @@ -2402,9 +2379,8 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME prepareCellFieldDoubleForWriting(f,0,split); for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) { - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(), - (char *)MED_NOGAUSS,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, - typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, + MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt); pt+=(*iter).getNbOfTuple()*nbComp; } break; @@ -2412,8 +2388,8 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME case ParaMEDMEM::ON_NODES: { int nbOfTuples=f->getArray()->getNumberOfTuples(); - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfTuples,(char *)MED_NOGAUSS, - MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_NOEUD,MED_NONE,numdt,(char *)"",dt,numo); + MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE,MED_NONE,MED_COMPACT_PFLMODE, + MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfTuples,(const unsigned char*)pt); break; } case ParaMEDMEM::ON_GAUSS_PT: @@ -2423,20 +2399,20 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME int idGp=0; for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) { - char *nomGauss=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + INTERP_KERNEL::AutoPtr nomGauss=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); std::ostringstream oss; oss << "GP_" << f->getName() << idGp++; - MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,nomGauss,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,nomGauss,MEDLoader::_TOO_LONG_STR); int id=f->getGaussLocalizationIdOfOneType((*iter).getType()); const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id); - MEDgaussEcr(fid,typmai3[(int)(*iter).getType()],(med_float*)&gl.getRefCoords()[0],MED_FULL_INTERLACE,gl.getNumberOfGaussPt(), - (med_float*)&gl.getGaussCoords()[0], - (med_float*)&gl.getWeights()[0],nomGauss); - int nbOfValues=gl.getNumberOfGaussPt()*f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues, - nomGauss,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, - typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + MEDlocalizationWr(fid,nomGauss,typmai3[(int)(*iter).getType()],mesh->getMeshDimension(),&gl.getRefCoords()[0],MED_FULL_INTERLACE, + gl.getNumberOfGaussPt(),&gl.getGaussCoords()[0],&gl.getWeights()[0],MED_NO_INTERPOLATION, MED_NO_MESH_SUPPORT); + int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); + int nbOfValues=gl.getNumberOfGaussPt()*nbOfEntity; + INTERP_KERNEL::AutoPtr fieldname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fieldname,MEDLoader::_TOO_LONG_STR); + MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, + MED_ALLENTITIES_PROFILE,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt); pt+=nbOfValues*nbComp; - delete [] nomGauss; } break; } @@ -2447,10 +2423,10 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) { int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes(); - int nbOfValues=nbPtPerCell*f->getMesh()->getNumberOfCellsWithType((*iter).getType()); - MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues, - (char *)MED_GAUSS_ELNO,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, - typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType()); + int nbOfValues=nbPtPerCell*nbOfEntity; + MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_NODE_ELEMENT,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE, + MED_ALLENTITIES_PROFILE,MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt); pt+=nbOfValues*nbComp; } break; @@ -2458,8 +2434,7 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME default: throw INTERP_KERNEL::Exception("Not managed this type of FIELD !"); } - delete [] nommaa; - MEDfermer(fid); + MEDfileClose(fid); if(renum) ((ParaMEDMEM::MEDCouplingFieldDouble *)f)->decrRef(); } @@ -2475,7 +2450,7 @@ void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCoupling const MEDCouplingUMesh *meshC=dynamic_cast(mesh); if(!meshC) throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); - if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2)) + if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) throw INTERP_KERNEL::Exception("Unstructuded mesh has not consecutive cell types !"); const int *connI=meshC->getNodalConnectivityIndex()->getConstPointer(); const int *conn=meshC->getNodalConnectivity()->getConstPointer(); @@ -2515,12 +2490,10 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDM writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering); if(isRenumbering) { - ParaMEDMEM::MEDCouplingFieldDouble *f2=f->clone(true); - DataArrayInt *da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + MEDCouplingAutoRefCountObjectPtr f2=f->clone(true); + MEDCouplingAutoRefCountObjectPtr da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); f2->renumberCells(da->getConstPointer(),false); - da->decrRef(); appendFieldDirectly(fileName,f2); - f2->decrRef(); } else appendFieldDirectly(fileName,f); @@ -2547,16 +2520,13 @@ void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const oss << "\" but meshdimension does not match !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDCouplingUMesh *m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); - MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh()); + MEDCouplingAutoRefCountObjectPtr m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); + MEDCouplingAutoRefCountObjectPtr m2=MEDCouplingUMesh::MergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh()); bool areNodesMerged; int newNbOfNodes; - DataArrayInt *da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes); if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes()) { - da->decrRef(); - m2->decrRef(); - m->decrRef(); std::ostringstream oss; oss << "Nodes in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit coordinates of unstructured grid f->getMesh() !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } @@ -2564,23 +2534,16 @@ void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const { case ParaMEDMEM::ON_CELLS: { - da->decrRef(); - DataArrayInt *da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL); + MEDCouplingAutoRefCountObjectPtr da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL); if(m2->getNumberOfCells()!=m->getNumberOfCells()) { - da2->decrRef(); - m2->decrRef(); - m->decrRef(); std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !"; throw INTERP_KERNEL::Exception(oss1.str().c_str()); } da=m2->convertCellArrayPerGeoType(da2); - DataArrayInt *da3=da->substr(m2->getNumberOfCells()); - da2->decrRef(); + MEDCouplingAutoRefCountObjectPtr da3=da->substr(m2->getNumberOfCells()); da2=m2->convertCellArrayPerGeoType(da3); - da3->decrRef(); appendCellProfileField(fileName,f,da2->getConstPointer()); - da2->decrRef(); break; } case ParaMEDMEM::ON_NODES: @@ -2590,15 +2553,9 @@ void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const } default: { - da->decrRef(); - m2->decrRef(); - m->decrRef(); throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS."); } } - da->decrRef(); - m2->decrRef(); - m->decrRef(); } void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) @@ -2680,7 +2637,7 @@ void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshName } if(meshes.empty()) throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); - DataArrayDouble *coords=meshes.front()->getCoords(); + const DataArrayDouble *coords=meshes.front()->getCoords(); for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) if(coords!=(*iter)->getCoords()) throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); @@ -2730,7 +2687,7 @@ void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshN } if(meshes.empty()) throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); - DataArrayDouble *coords=meshes.front()->getCoords(); + const DataArrayDouble *coords=meshes.front()->getCoords(); for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) if(coords!=(*iter)->getCoords()) throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); @@ -2772,7 +2729,7 @@ void MEDLoader::WriteUMeshes(const char *fileName, const std::vectorgetName()); if(meshName.empty()) throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change name of first element of 2nd parameter !"); - DataArrayDouble *coords=meshes.front()->getCoords(); + const DataArrayDouble *coords=meshes.front()->getCoords(); for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) if(coords!=(*iter)->getCoords()) throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); @@ -2864,8 +2821,5 @@ void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const Pa std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - std::string fieldName(f->getName()); - if(fieldName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !"); MEDLoaderNS::appendFieldDirectly(fileName,f); } diff --git a/src/MEDLoader/MEDLoader.hxx b/src/MEDLoader/MEDLoader.hxx index 307dcdade..4745677a8 100644 --- a/src/MEDLoader/MEDLoader.hxx +++ b/src/MEDLoader/MEDLoader.hxx @@ -94,7 +94,7 @@ class MEDLOADER_EXPORT MEDLoader static std::vector GetMeshGroupsNamesOnFamily(const char *fileName, const char *meshName, const char *famName) throw(INTERP_KERNEL::Exception); static std::vector GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception); static std::vector GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); - static std::vector GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetTypesOfField(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception); static std::vector GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); static std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); static std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); @@ -110,15 +110,15 @@ class MEDLOADER_EXPORT MEDLoader static int ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); static std::vector ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception); + const std::vector >& its) throw(INTERP_KERNEL::Exception); static std::vector ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception); + const std::vector >& its) throw(INTERP_KERNEL::Exception); static std::vector ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception); + const std::vector >& its) throw(INTERP_KERNEL::Exception); static std::vector ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception); + const std::vector >& its) throw(INTERP_KERNEL::Exception); static std::vector ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, - const std::vector >& its) throw(INTERP_KERNEL::Exception); + const std::vector >& its) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDLoaderBase.cxx b/src/MEDLoader/MEDLoaderBase.cxx index 3dc6aad58..afe59a542 100644 --- a/src/MEDLoader/MEDLoaderBase.cxx +++ b/src/MEDLoader/MEDLoaderBase.cxx @@ -117,6 +117,32 @@ void MEDLoaderBase::safeStrCpy(const char *src, int maxLgth, char *dest, int beh strcpy(dest,src); } +/*! + * This method is equivalent to MEDLoaderBase::safeStrCpy except that here no '\0' car is put. + * This method should be used for multi string in one string. + */ +void MEDLoaderBase::safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception) +{ + if((int)strlen(src)>maxLgth) + { + if(behaviour==0 || behaviour>1) + { + std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else if(behaviour==1) + { + std::string s=zipString(src,maxLgth); + std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; + std::cerr << "zipping to : " << s << "\n"; + strcpy(dest,s.c_str()); + return ; + } + } + int n=strlen(src); + strncpy(dest,src,n); +} + std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth) { std::string ret(expr,lgth); diff --git a/src/MEDLoader/MEDLoaderBase.hxx b/src/MEDLoader/MEDLoaderBase.hxx index 09e0c5850..0ab2a6ea7 100644 --- a/src/MEDLoader/MEDLoaderBase.hxx +++ b/src/MEDLoader/MEDLoaderBase.hxx @@ -34,6 +34,7 @@ public: static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit); static void strip(std::string& s); static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception); + static void safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception); static std::string buildStringFromFortran(const char *expr, int lgth); static void zipEqualConsChar(std::string& s, int minConsSmChar); static std::string zipString(const char *src, int sizeToRespect); diff --git a/src/MEDLoader/Makefile.am b/src/MEDLoader/Makefile.am index 500d698e4..0402228e2 100755 --- a/src/MEDLoader/Makefile.am +++ b/src/MEDLoader/Makefile.am @@ -51,4 +51,4 @@ libmedloader_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ -I$(srcdir)/../MEDCoupling libmedloader_la_LDFLAGS= ../MEDCoupling/libmedcoupling.la \ -../INTERP_KERNEL/libinterpkernel.la $(MED2_LIBS) $(HDF5_LIBS) +../INTERP_KERNEL/libinterpkernel.la $(MED2_LIBS_C_ONLY) $(HDF5_LIBS) diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i index 40e445af8..d1320995b 100644 --- a/src/MEDLoader/Swig/MEDLoader.i +++ b/src/MEDLoader/Swig/MEDLoader.i @@ -27,6 +27,7 @@ %{ #include "MEDLoader.hxx" #include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" #include "MEDLoaderTypemaps.i" using namespace ParaMEDMEM; @@ -49,25 +50,32 @@ using namespace ParaMEDMEM; %newobject MEDLoader::ReadFieldNode; %newobject MEDLoader::ReadFieldGauss; %newobject MEDLoader::ReadFieldGaussNE; +%newobject ParaMEDMEM::MEDFileMesh::New; +%newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel; +%newobject ParaMEDMEM::MEDFileMesh::getGroupArr; +%newobject ParaMEDMEM::MEDFileMesh::getGroupsArr; +%newobject ParaMEDMEM::MEDFileMesh::getFamilyArr; +%newobject ParaMEDMEM::MEDFileMesh::getFamiliesArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupsArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeFamilyArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr; %newobject ParaMEDMEM::MEDFileUMesh::New; %newobject ParaMEDMEM::MEDFileUMesh::getCoords; %newobject ParaMEDMEM::MEDFileUMesh::getGroup; %newobject ParaMEDMEM::MEDFileUMesh::getGroups; %newobject ParaMEDMEM::MEDFileUMesh::getFamily; %newobject ParaMEDMEM::MEDFileUMesh::getFamilies; -%newobject ParaMEDMEM::MEDFileUMesh::getGroupArr; -%newobject ParaMEDMEM::MEDFileUMesh::getGroupsArr; -%newobject ParaMEDMEM::MEDFileUMesh::getFamilyArr; -%newobject ParaMEDMEM::MEDFileUMesh::getFamiliesArr; -%newobject ParaMEDMEM::MEDFileUMesh::getNodeGroupArr; -%newobject ParaMEDMEM::MEDFileUMesh::getNodeGroupsArr; -%newobject ParaMEDMEM::MEDFileUMesh::getNodeFamilyArr; -%newobject ParaMEDMEM::MEDFileUMesh::getNodeFamiliesArr; %newobject ParaMEDMEM::MEDFileUMesh::getMeshAtLevel; %newobject ParaMEDMEM::MEDFileUMesh::getLevel0Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; %newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; +%newobject ParaMEDMEM::MEDFileCMesh::New; + +%newobject ParaMEDMEM::MEDFileFields::New; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::New; +%newobject ParaMEDMEM::MEDFileField1TS::New; class MEDLoader { @@ -171,9 +179,9 @@ public: std::vector v=convertUMeshVecFromPy(li); MEDLoader::WriteUMeshes(fileName,v,writeFromScratch); } - static PyObject *GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception) + static PyObject *GetTypesOfField(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { - std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,fieldName,meshName); + std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,meshName,fieldName); int size=v.size(); PyObject *ret=PyList_New(size); for(int i=0;i& getFamilyInfo() const; + const std::map >& getGroupInfo() const; + std::vector getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception); + std::vector getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception); + std::vector getGroupsNames() const; + std::vector getFamiliesNames() const; + void removeGroup(const char *name) throw(INTERP_KERNEL::Exception); + void removeFamily(const char *name) throw(INTERP_KERNEL::Exception); + 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 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); + std::vector getFamiliesIds(const std::vector& famNames) const throw(INTERP_KERNEL::Exception); + std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); + // + virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); + virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); + virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupArr(const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamilyArr(const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getTime() + { + int tmp1,tmp2; + double tmp0=self->getTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_double(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + virtual PyObject *isEqual(const MEDFileMesh *other, double eps) const + { + std::string what; + bool ret0=self->isEqual(other,eps,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + PyObject *areFamsEqual(const MEDFileMesh *other) const + { + std::string what; + bool ret0=self->areFamsEqual(other,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + PyObject *areGrpsEqual(const MEDFileMesh *other) const + { + std::string what; + bool ret0=self->areGrpsEqual(other,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + PyObject *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getFamilyFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getNumberFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + } + }; + + class MEDFileUMesh : public MEDFileMesh + { + public: + 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(); + ~MEDFileUMesh(); + // + int getMeshDimension() const; + std::vector getNonEmptyLevels() const; + std::vector getNonEmptyLevelsExt() const; + DataArrayDouble *getCoords() const; + MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeGroupArr(const char *grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeFamilyArr(const char *fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + // + 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 setFamilyField(DataArrayInt *arr, const std::vector< std::vector< int > > &userfids, const std::vector& grpNames, bool renum=false) throw(INTERP_KERNEL::Exception); + void addNodeGroup(const std::string& name, const std::vector& ids) throw(INTERP_KERNEL::Exception); + void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); + void setMeshAtLevelOld(int meshDimRelToMax, MEDCouplingUMesh *m) 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); + %extend + { + PyObject *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getRevNumberFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + void setGroupsAtLevel(int meshDimRelToMaxExt, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector grps; + convertPyObjToVecDataArrayIntCst(li,grps); + self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); + } + } + }; + + class MEDFileCMesh : public 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); + void setMesh(MEDCouplingCMesh *m); + %extend + { + PyObject *getMesh() const + { + const MEDCouplingCMesh *tmp=self->getMesh(); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 ); + } + } + }; + + class MEDFieldFieldGlobs + { + public: + std::vector getPfls() const; + std::vector getLocs() const; + }; + + class MEDFileField1TSWithoutDAS : public RefCountObject + { + public: + int getIteration() const; + int getOrder() const; + std::string getName(); + std::string getMeshName(); + int getNumberOfComponents() const; + const std::vector& getInfos() const; + std::vector getPflsReallyUsed() const; + std::vector getLocsReallyUsed() const; + }; + + class MEDFileField1TS : public MEDFileField1TSWithoutDAS, public MEDFieldFieldGlobs + { + public: + static MEDFileField1TS *New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + }; + + class MEDFileFieldMultiTSWithoutDAS + { + public: + int getNumberOfTS() const; + }; + + class MEDFileFieldMultiTS : public MEDFileFieldMultiTSWithoutDAS, public MEDFieldFieldGlobs + { + public: + static MEDFileFieldMultiTS *New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); + }; + + class MEDFileFields : public RefCountObject, public MEDFieldFieldGlobs { - std::vector grps; - convertPyObjToVecDataArrayIntCst(li,grps); - self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); - } + public: + static MEDFileFields *New(const char *fileName) throw(INTERP_KERNEL::Exception); + int getNumberOfFields() const; + std::vector getPfls() const; + std::vector getLocs() const; + }; } diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py index 4aa95056b..081ec1dae 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest.py +++ b/src/MEDLoader/Swig/MEDLoaderTest.py @@ -74,6 +74,7 @@ class MEDLoaderTest(unittest.TestCase): MEDLoader.MEDLoader.WriteField("Pyfile7.med",f1,True); f2=MEDLoader.MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,"Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); pass def testFieldRW2(self): @@ -135,7 +136,6 @@ class MEDLoaderTest(unittest.TestCase): VAL2=-1111111111111.; name1="AField"; name3="AMesh1"; - name2="AMesh2"; f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); f1.getMesh().setName(name3); f1.setName(name1); @@ -146,14 +146,11 @@ class MEDLoaderTest(unittest.TestCase): f1.setTime(10.14,18,19); f1.getArray().setIJ(0,0,VAL2); MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name2); + f1.getMesh().setName(name3); f1.setTime(10.55,28,29); f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); vec=MEDLoader.MEDLoader.GetMeshNamesOnField(fileName,name1); - self.assertEqual(2,len(vec)); - self.assertTrue(vec[0]==name3); - self.assertTrue(vec[1]==name2); f1.setTime(10.66,38,39); f1.getArray().setIJ(0,0,3*VAL2); MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); @@ -163,7 +160,7 @@ class MEDLoaderTest(unittest.TestCase): #ON NODES f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); f1.setName(name1); - f1.getMesh().setName(name2); + f1.getMesh().setName(name3); f1.setTime(110.,8,9); MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1.setTime(110.,108,109); @@ -175,39 +172,35 @@ class MEDLoaderTest(unittest.TestCase): MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); # it1=MEDLoader.MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(2,len(it1)); + self.assertEqual(5,len(it1)); self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - it2=MEDLoader.MEDLoader.GetCellFieldIterations(fileName,name2,name1); - self.assertEqual(3,len(it2)); - self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]); - self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]); - self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]); - it3=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name2,name1); + self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); + self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); + self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); + it3=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name3,name1); self.assertEqual(3,len(it3)); self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - it4=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertTrue(len(it4)==0); # # f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); # - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9); + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109); + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209); + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); pass @@ -302,6 +295,8 @@ class MEDLoaderTest(unittest.TestCase): MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test # f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + tt=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); + self.assertEqual(tt,[MEDLoader.ON_CELLS]); f2.checkCoherency(); self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); # @@ -492,11 +487,11 @@ class MEDLoaderTest(unittest.TestCase): array.setValues(arr2,12,2) array.setInfoOnComponent(0,"plkj [mm]"); array.setInfoOnComponent(1,"pqqqss [mm]"); - f2.setTime(3.17,2,7); + f2.setTime(3.14,2,7); f2.checkCoherency(); # MEDLoader.MEDLoader.WriteField(fileName,f1,True); - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName()); + ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); self.assertEqual(1,len(ts)); self.assertEqual(MEDLoader.ON_CELLS,ts[0]); fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); @@ -507,7 +502,7 @@ class MEDLoaderTest(unittest.TestCase): self.assertEqual(1,len(fs)); self.assertTrue(fs[0]=="FieldMix"); # - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName()); + ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); self.assertEqual(2,len(ts)); self.assertEqual(MEDLoader.ON_NODES,ts[0]); self.assertEqual(MEDLoader.ON_CELLS,ts[1]); diff --git a/src/MEDLoader/Swig/MEDLoaderTest2.py b/src/MEDLoader/Swig/MEDLoaderTest2.py index b0ca6b1d4..c3cf5dfc1 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest2.py +++ b/src/MEDLoader/Swig/MEDLoaderTest2.py @@ -133,7 +133,6 @@ class MEDLoaderTest(unittest.TestCase): VAL2=-1111111111111.; name1="AField"; name3="AMesh1"; - name2="AMesh2"; f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); f1.getMesh().setName(name3); f1.setName(name1); @@ -144,10 +143,10 @@ class MEDLoaderTest(unittest.TestCase): f1.setTime(10.14,18,19); f1.getArray().setIJ(0,0,VAL2); MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name2); + f1.getMesh().setName(name3); f1.setTime(10.55,28,29); f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.WriteFieldDep(fileName,f1,False); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1.setTime(10.66,38,39); f1.getArray().setIJ(0,0,3*VAL2); MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); @@ -157,7 +156,7 @@ class MEDLoaderTest(unittest.TestCase): #ON NODES f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); f1.setName(name1); - f1.getMesh().setName(name2); + f1.getMesh().setName(name3); f1.setTime(110.,8,9); MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1.setTime(110.,108,109); @@ -169,39 +168,35 @@ class MEDLoaderTest(unittest.TestCase): MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); # it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(2,len(it1)); + self.assertEqual(5,len(it1)); self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - it2=MEDLoader.GetCellFieldIterations(fileName,name2,name1); - self.assertEqual(3,len(it2)); - self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]); - self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]); - self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]); - it3=MEDLoader.GetNodeFieldIterations(fileName,name2,name1); + self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); + self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); + self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); + it3=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); self.assertEqual(3,len(it3)); self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - it4=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertTrue(len(it4)==0); # # f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); # - f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9); + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109); + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209); + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); pass diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py index a78a56263..355de88e9 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ b/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -27,7 +27,7 @@ class MEDLoaderTest(unittest.TestCase): def testMEDMesh1(self): fileName="Pyfile18.med" mname="ExampleOfMultiDimW" - medmesh=MEDFileUMesh.New(fileName,mname) + medmesh=MEDFileMesh.New(fileName,mname) self.assertEqual((0,-1),medmesh.getNonEmptyLevels()) m1_0=medmesh.getLevel0Mesh(True) m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) @@ -69,13 +69,13 @@ class MEDLoaderTest(unittest.TestCase): self.assertEqual([2,3,5,14,16],medmesh.getFamiliesArr(0,["Family_4","Family_2"],True).getValues()); self.assertEqual([19,2,3,4,5,14,15,16],medmesh.getGroupsArr(0,["mesh2","mesh4","mesh3"],True).getValues()); famn=medmesh.getFamilyNameGivenId(0) - self.assertEqual(range(60),medmesh.getNodeFamilyArr(famn,True).getValues()); + self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,True); #without renum self.assertEqual([2,3,5,14,16],medmesh.getGroupArr(0,"mesh2",False).getValues()); self.assertEqual([2,3,16],medmesh.getFamilyArr(0,"Family_2",False).getValues()); self.assertEqual([2,3,5,14,16],medmesh.getFamiliesArr(0,["Family_4","Family_2"],False).getValues()); self.assertEqual([0,2,3,4,5,14,15,16],medmesh.getGroupsArr(0,["mesh2","mesh3","mesh4"],False).getValues()); - self.assertEqual(range(60),medmesh.getNodeFamilyArr(famn,False).getValues()); + self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,False); pass # this tests emulates MEDMEM ( Except that it works ! ) The permutation are NOT taken into account @@ -169,6 +169,8 @@ class MEDLoaderTest(unittest.TestCase): coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] c.setValues(coords,9,2) + c.setInfoOnComponent(0,"abcdef [km]") + c.setInfoOnComponent(1,"ghij [MW]") m=MEDCouplingUMesh.New(); m.setMeshDimension(2); m.allocateCells(5); @@ -206,7 +208,7 @@ class MEDLoaderTest(unittest.TestCase): mm.setCoords(c) renumNode=DataArrayInt.New() renumNode.setValues([10,11,12,13,14,15,16,17,18],9,1) - mm.setRenumArr(1,renumNode) + mm.setRenumFieldArr(1,renumNode) mm.setMeshAtLevel(-1,m1); mm.setMeshAtLevel(0,m); mm.setMeshAtLevel(-2,m2); @@ -243,6 +245,63 @@ class MEDLoaderTest(unittest.TestCase): self.assertTrue(g2_1.isEqual(t)); # mm.write(outFileName,2); + mm2=MEDFileMesh.New(outFileName) + res=mm.isEqual(mm2,1e-12) + self.assertTrue(res[0]) + pass + + #testing persistence of retrieved arrays + def testMEDMesh5(self): + fileName="Pyfile18.med" + mname="ExampleOfMultiDimW" + medmesh=MEDFileUMesh.New(fileName,mname) + m1_0=medmesh.getLevel0Mesh(True) + da1=medmesh.getFamilyFieldAtLevel(0) + del medmesh + self.assertEqual(20,m1_0.getNumberOfCells()) + self.assertEqual(20,da1.getNumberOfTuples()) + pass + + def testMEDMesh6(self): + outFileName="MEDFileMesh5.med" + m=MEDFileCMesh.New() + m.setTime(2.3,-1,-1) + m1=MEDCouplingCMesh.New(); + da=DataArrayDouble.New() + da.setValues([0.,1.,2.],3,1) + da.setInfoOnComponent(0,"XX [mm]") + m1.setCoordsAt(0,da) + da=DataArrayDouble.New() + da.setValues([0.,1.2],2,1) + da.setInfoOnComponent(0,"YY [km]") + m1.setCoordsAt(1,da) + da=DataArrayDouble.New() + da.setValues([0.,1.3],2,1) + da.setInfoOnComponent(0,"ZZ [um]") + m1.setCoordsAt(2,da) + m.setMesh(m1) + m.setName("myFirstCartMesh") + m.setDescription("mmmmpppppppp") + m.setTimeValue(2.3) + m.setTimeUnit("ms") + da=DataArrayInt.New() + da.setValues([0,0,1,0,1,2,4,3,0,1,2,2],12,1) + m.setFamilyFieldArr(1,da) + m.setFamilyId("family1",1) + da=m.getFamilyArr(1,"family1") + expected1=[2,4,9] + self.assertEqual(expected1,da.getValues()) + m.write(outFileName,2); + mm=MEDFileMesh.New(outFileName) + self.assertTrue(m.isEqual(mm,1e-12)[0]) + self.assertEqual(expected1,mm.getFamilyArr(1,"family1").getValues()) + m2=mm.getMesh() + tt=m.getTime() + m1.setTime(tt[0],tt[1],tt[2]) + m1.setName(m.getName()) + m1.setTimeUnit(m.getTimeUnit()) + m1.setDescription(m.getDescription()) + self.assertTrue(m2.isEqual(m1,1e-12)); pass pass diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx index 341fa6bfe..55d13658b 100644 --- a/src/MEDLoader/Test/MEDLoaderTest.cxx +++ b/src/MEDLoader/Test/MEDLoaderTest.cxx @@ -99,6 +99,9 @@ void MEDLoaderTest::testFieldRW1() MEDLoader::WriteField("file7.med",f1,true); f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName(),0,f1->getName(),2,3); CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + // testing kind message on error of field type. + CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell("file7.med",f1->getMesh()->getName(),0,f1->getName(),2,3),INTERP_KERNEL::Exception); + // f1->decrRef(); f2->decrRef(); } @@ -178,7 +181,6 @@ void MEDLoaderTest::testFieldRW3() static const double VAL2=-1111111111111.; const char name1[]="AField"; const char name3[]="AMesh1"; - const char name2[]="AMesh2"; MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); ((MEDCouplingMesh *)f1->getMesh())->setName(name3); f1->setName(name1); @@ -189,14 +191,9 @@ void MEDLoaderTest::testFieldRW3() f1->setTime(10.14,18,19); tmp[0]=VAL2; MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - ((MEDCouplingMesh *)f1->getMesh())->setName(name2); f1->setTime(10.55,28,29); tmp[0]=3*VAL1; - MEDLoader::WriteField(fileName,f1,false); - std::vector vec=MEDLoader::GetMeshNamesOnField(fileName,name1); - CPPUNIT_ASSERT_EQUAL(2,(int)vec.size()); - CPPUNIT_ASSERT(vec[0]==name3); - CPPUNIT_ASSERT(vec[1]==name2); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(10.66,38,39); tmp[0]=3*VAL2; MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); @@ -207,7 +204,7 @@ void MEDLoaderTest::testFieldRW3() f1->decrRef(); f1=buildVecFieldOnNodes_1(); f1->setName(name1); - ((MEDCouplingMesh *)f1->getMesh())->setName(name2); + ((MEDCouplingMesh *)f1->getMesh())->setName(name3); f1->setTime(110.,8,9); MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); f1->setTime(110.,108,109); @@ -219,21 +216,17 @@ void MEDLoaderTest::testFieldRW3() MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); // std::vector< std::pair > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT_EQUAL(2,(int)it1.size()); + CPPUNIT_ASSERT_EQUAL(5,(int)it1.size()); CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); - std::vector< std::pair > it2=MEDLoader::GetCellFieldIterations(fileName,name2,name1); - CPPUNIT_ASSERT_EQUAL(3,(int)it2.size()); - CPPUNIT_ASSERT_EQUAL(28,it2[0].first); CPPUNIT_ASSERT_EQUAL(29,it2[0].second); - CPPUNIT_ASSERT_EQUAL(38,it2[1].first); CPPUNIT_ASSERT_EQUAL(39,it2[1].second); - CPPUNIT_ASSERT_EQUAL(48,it2[2].first); CPPUNIT_ASSERT_EQUAL(49,it2[2].second); - std::vector< std::pair > it3=MEDLoader::GetNodeFieldIterations(fileName,name2,name1); + CPPUNIT_ASSERT_EQUAL(28,it1[2].first); CPPUNIT_ASSERT_EQUAL(29,it1[2].second); + CPPUNIT_ASSERT_EQUAL(38,it1[3].first); CPPUNIT_ASSERT_EQUAL(39,it1[3].second); + CPPUNIT_ASSERT_EQUAL(48,it1[4].first); CPPUNIT_ASSERT_EQUAL(49,it1[4].second); + std::vector< std::pair > it3=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); - std::vector< std::pair > it4=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT(it4.empty()); // f1->decrRef(); // @@ -243,23 +236,23 @@ void MEDLoaderTest::testFieldRW3() f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,28,29); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,28,29); CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,38,39); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,38,39); CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,48,49); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,48,49); CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); f1->decrRef(); // - f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,8,9); + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,8,9); CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,108,109); + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,108,109); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,208,209); + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,208,209); CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); f1->decrRef(); } @@ -379,6 +372,9 @@ void MEDLoaderTest::testFieldProfilRW1() MEDLoader::WriteField(fileName,f1,false);//<- false important for the test // MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7); + std::vector types=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName(),f1->getName()); + CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); + CPPUNIT_ASSERT(types[0]==ON_CELLS); f2->checkCoherency(); CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); // @@ -673,11 +669,11 @@ void MEDLoaderTest::testMixCellAndNodesFieldRW1() 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. }; std::copy(arr2,arr2+24,tmp); - f2->setTime(3.17,2,7); + f2->setTime(3.14,2,7); f2->checkCoherency(); // MEDLoader::WriteField(fileName,f1,true); - std::vector ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName()); + std::vector ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName(),f1->getName()); CPPUNIT_ASSERT_EQUAL(1,(int)ts.size()); CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]); std::vector fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName()); @@ -688,7 +684,7 @@ void MEDLoaderTest::testMixCellAndNodesFieldRW1() CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); CPPUNIT_ASSERT(fs[0]=="FieldMix"); // - ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName()); + ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName(),f1->getName()); CPPUNIT_ASSERT_EQUAL(2,(int)ts.size()); CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]); CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]); diff --git a/src/ParaMEDMEM/OverlapDEC.cxx b/src/ParaMEDMEM/OverlapDEC.cxx index 27df459b7..4ac0dfdf0 100644 --- a/src/ParaMEDMEM/OverlapDEC.cxx +++ b/src/ParaMEDMEM/OverlapDEC.cxx @@ -23,7 +23,138 @@ #include "MPIProcessorGroup.hxx" #include "OverlapElementLocator.hxx" #include "OverlapInterpolationMatrix.hxx" +/*! + \defgroup overlapdec OverlapDEC + The OverlapDEC enables the \ref InterpKerRemapGlobal "conservative remapping" of fields between two parallel codes. This remapping is based on the computation of intersection volumes on a \b same \b processor \b group. On this processor group is defined a field template defined on A and an another on B. The computation is possible for 3D meshes, 2D meshes, 3D-surface meshes, 1D meshes and 2D-curve meshes. Dimensions must be similar for code A and code B. + The main difference with \ref interpkerneldec is that this DEC manage 2 field-templates on each process in processor group A and B called in code source and target. + Furthermore all process in process group cooperates in global interpolation matrix computation. In this sense InterpKernelDEC is a specialization of OverlapDEC. + \section ParaMEDMEMOverlapDECAlgorithmDescription Algorithm Description + + Let's consider the following use case that is ran in ParaMEDMEMTest_OverlapDEC.cxx to describes the different steps in computation. Processor group contains 3 processors. + \anchor ParaMEDMEMOverlapDECImgTest1 + \image html OverlapDEC1.png "Example showing the use case to explain the different steps." + + \subsection ParaMEDMEMOverlapDECAlgoStep1 Step 1 : Bounding box exchange and global interaction between procs computation. + + In order to reduce as fas as possible number of exchange among processors every procs computes a bounding box for A and B. Then a AllToAll is performed so that + every procs can compute the \b global interactions between procs. + This computation leads every procs to compute the same global TODO list expressed as a list of pair. A pair (x,y) means that proc \b x fieldtemplate A can interacts (because bounding boxes interacts) with fieltemplate B of proc \b y. + In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following a \b global TODO list : + + \b (0,0),(0,1),(1,0),(1,2),(2,0),(2,1),(2,2) + + Here pair (0,2) does not appear because bounding box of fieldtemplateA of proc#2 does not interact with proc#0 of fieldtemplate B. + + Stage performed by ParaMEDMEM::OverlapElementLocator::computeBoundingBoxes. + + \subsection ParaMEDMEMOverlapDECAlgoStep2 Step 2 : Computation of local TODO list + + Starting from global interaction previously computed in \ref ParaMEDMEMOverlapDECAlgoStep1 "Step 1", each proc computes the TODO list per proc. + The following rules is chosen : a pair (x,y) can be treated by either proc #x or proc #y, in order to reduce the amount of data transfert accross + procs. The algorithm chosen for loadbalancing is the following : Each proc as an empty \b local TODO list at the beginning. The for each pair (k,m) in + \b global TODO list if proc#k has less temporary local list than proc#m pair (k,m) is added to temparary local TODO list of proc#k. + If proc#m has less temporary local TODO list than proc#k pair (k,m) is added to temparary local TODO list of proc#m. + If proc#k and proc#m have the same amount of temporary local TODO list pair (k,m) is added to temparary local TODO list of proc#k. + + In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" this computation leads to the following a local TODO list : + + - proc#0 : (0,0) + - proc#1 : (0,1),(1,0) + - proc#2 : (1,2),(2,0),(2,1),(2,2) + + Stage performed by ParaMEDMEM::OverlapElementLocator::computeBoundingBoxes too. + + The algorithm described here is not perfect for this use case. It will be enhanced soon, I hope. + + At this stage each proc knows precisely its \b local TODO list (at interpolation sense). The \b local TODO list of other procs than local + is kept for future computation. + + \subsection ParaMEDMEMOverlapDECAlgoStep3 Step 3 : Matrix echange between procs + + At this step knows its \b local TODO list, the aim now is to exchange field-templates between procs. Each proc computes knowing TODO list per + proc computed in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step 2" the exchange TODO list : + + In the \ref ParaMEDMEMOverlapDECImgTest1 "example above" the exchange TODO list gives the following results : + + Sending TODO list per proc : + + - proc #0 : Send fieldtemplate A to Proc#1, Send fieldtemplate B to Proc#1, Send fieldtemplate B to Proc#2 + - Proc #1 : Send fieldtemplate A to Proc#2, Send fieldtemplate B to Proc#2 + - Proc #2 : No send. + + Receiving TODO list per proc : + + - proc #0 : No receiving + - proc #1 : receiving fieldtemplate A from Proc#0, receiving fieldtemplate B from Proc#0 + - proc #2 : receiving fieldtemplate B from Proc#0, receiving fieldtemplate A from Proc#1, receiving fieldtemplate B from Proc#1 + + To avoid as far as possible big amount of exchange between procs only relevant part of mesh. For a proc#k sending fieldtemplate A to fieldtemplate B + of proc #m. In this case proc#k computes part of mesh A in boundingbox B of proc#m. It implies that the corresponding cellIds or nodeIds of + corresponding part are sent to proc #m too. + + Let's consider the couple (k,m) in TODO list. This couple is treated by either k or m as seen \ref ParaMEDMEMOverlapDECAlgoStep2 "here in Step2". + + As it will be dealt in Step 6, at the end for final matrix-vector computation the result matrix of the couple (k,m) anywhere it is computed (proc #k or proc #m) + it will be stored in \b proc#m. + + - If proc #k is in charge (performs matrix computation) of this couple (k,m) target ids (cells or nodes) of mesh in proc #m are renumbered, because proc #m has stripped + its target mesh to avoid big amount of data to transfer. In this case as it is finally proc #m in charge finally of the matrix, proc #k must keep preciously the + source ids needed to be sent to proc#m. No problem will appear for matrix assembling in proc m, for source ids because no restriction done. + Concerning source ids to be sent for matrix-vector computation, proc k will known precisely which source ids field values to send to proc #m. + This is incarnated by OverlapMapping::keepTracksOfTargetIds in proc m. + + - If proc #m is in charge (performs matrix computation) of this couple (k,m) source ids (cells or nodes) of mesh in proc #k are renumbered, because proc #k has stripped + its source mesh to avoid big amount of data to transfer. In this case as it is finally proc #m in charge finally of the matrix, proc #m receive the source ids + from remote proc #k so the matrix is directly OK, no need of renumbering will be needed in \ref ParaMEDMEMOverlapDECAlgoStep5 "Step 5". But proc k must + keep tracks of sent ids to proc m for matrix-vector computation. + This is incarnated by OverlapMapping::keepTracksOfSourceIds in proc k. + + This step is performed in ParaMEDMEM::OverlapElementLocator::exchangeMeshes method. + + \subsection ParaMEDMEMOverlapDECAlgoStep4 Step 4 : The interpolation matrix computation + + After mesh exchange in \ref ParaMEDMEMOverlapDECAlgoStep3 "Step3" each proc has all information to perform its \b local TODO list computed in + \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". This step is so potentially CPU costly. That's why the \b local TODO list per proc is expected to + be as well balanced as possible. + + The interpolation is performed as \ref ParaMEDMEM::MEDCouplingRemapper "Remapper" does. + + This operation is performed by OverlapInterpolationMatrix::addContribution method. + + \subsection ParaMEDMEMOverlapDECAlgoStep5 Step 5 : Global matrix construction. + + After having performed the TODO list at the end of \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4" it is needed to assemble the final matrix. + + The final aim is to have a distributed matrix \f$ M_k \f$ on each proc#k. In order to reduce data exchange during matrix product process. + \f$ M_k \f$ is built using sizeof(Proc group) \c std::vector< \c std::map \c >. + + For a proc#k, it is necessary to fetch info of all matrix built in \ref ParaMEDMEMOverlapDECAlgoStep4 "Step4" where the first element in pair + is equal to k. + + After this step, the matrix repartition is the following after call ParaMEDMEM::OverlapMapping::prepare : + + - proc#0 : (0,0),(1,0),(2,0) + - proc#1 : (0,1),(2,1) + - proc#2 : (1,2),(2,2) + + Tuple (2,1) computed on proc 2 is stored at the end of "prepare" in proc 1. So it is an example of item 0 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". + Tuple (0,1) computed on proc 1 and stored in proc 1 too. So it is an example of item 1 in \ref ParaMEDMEMOverlapDECAlgoStep2 "Step2". + + In ParaMEDMEM::OverlapMapping::_proc_ids_to_send_vector_st will contain : + + - Proc#0 : 0,1 + - Proc#1 : 0,2 + - Proc#2 : 0,1,2 + + In ParaMEDMEM::OverlapMapping::_proc_ids_to_recv_vector_st will contain : + + - Proc#0 : 0,1,2 + - Proc#1 : 0,2 + - Proc#2 : 1,2 + + The method in charge to perform this is : ParaMEDMEM::OverlapMapping::prepare. +*/ namespace ParaMEDMEM { OverlapDEC::OverlapDEC(const std::set& procIds, const MPI_Comm& world_comm):_own_group(true),_interpolation_matrix(0), @@ -72,12 +203,13 @@ namespace ParaMEDMEM void OverlapDEC::sendData() { - throw INTERP_KERNEL::Exception("Not implemented yet !!!!"); + _interpolation_matrix->multiply(); } void OverlapDEC::recvData() { - _interpolation_matrix->transposeMultiply();; + throw INTERP_KERNEL::Exception("Not implemented yet !!!!"); + //_interpolation_matrix->transposeMultiply(); } void OverlapDEC::synchronize() @@ -88,7 +220,7 @@ namespace ParaMEDMEM _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this); OverlapElementLocator locator(_source_field,_target_field,*_group); locator.copyOptions(*this); - locator.exchangeMeshes(); + locator.exchangeMeshes(*_interpolation_matrix); std::vector< std::pair > jobs=locator.getToDoList(); std::string srcMeth=locator.getSourceMethod(); std::string trgMeth=locator.getTargetMethod(); @@ -98,7 +230,7 @@ namespace ParaMEDMEM const DataArrayInt *srcIds=locator.getSourceIds((*it).first); const MEDCouplingPointSet *trg=locator.getTargetMesh((*it).second); const DataArrayInt *trgIds=locator.getTargetIds((*it).second); - _interpolation_matrix->addContribution(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).first); + _interpolation_matrix->addContribution(src,srcIds,srcMeth,(*it).first,trg,trgIds,trgMeth,(*it).second); } _interpolation_matrix->prepare(locator.getProcsInInteraction()); _interpolation_matrix->computeDeno(); diff --git a/src/ParaMEDMEM/OverlapElementLocator.cxx b/src/ParaMEDMEM/OverlapElementLocator.cxx index af751cdca..628350f3c 100644 --- a/src/ParaMEDMEM/OverlapElementLocator.cxx +++ b/src/ParaMEDMEM/OverlapElementLocator.cxx @@ -27,6 +27,7 @@ #include "ParaMESH.hxx" #include "ProcessorGroup.hxx" #include "MPIProcessorGroup.hxx" +#include "OverlapInterpolationMatrix.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldDiscretization.hxx" #include "DirectedBoundingBox.hxx" @@ -156,7 +157,7 @@ namespace ParaMEDMEM * The aim of this method is to perform the communication to get data corresponding to '_to_do_list' attribute. * The principle is the following : if proc n1 and n2 need to perform a cross sending with n1 >::const_iterator it2=_procs_to_send.begin();it2!=_procs_to_send.end();it2++) - sendLocalMeshTo((*it2).first,(*it2).second); + sendLocalMeshTo((*it2).first,(*it2).second,matrix); //fetching remaining meshes for(std::vector< std::pair >::const_iterator it=toDoListForFetchRemaining.begin();it!=toDoListForFetchRemaining.end();it++) { @@ -266,8 +267,10 @@ namespace ParaMEDMEM /*! * This methods sends local source if 'sourceOrTarget'==True to proc 'procId'. * This methods sends local target if 'sourceOrTarget'==False to proc 'procId'. + * + * This method prepares the matrix too, for matrix assembling and future matrix-vector computation. */ - void OverlapElementLocator::sendLocalMeshTo(int procId, bool sourceOrTarget) const + void OverlapElementLocator::sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const { vector elems; //int myProcId=_group.myRank(); @@ -288,7 +291,11 @@ namespace ParaMEDMEM } local_mesh->getCellsInBoundingBox(distant_bb,getBoundingBoxAdjustment(),elems); DataArrayInt *idsToSend; - MEDCouplingPointSet *send_mesh=(MEDCouplingPointSet *)field->getField()->buildSubMeshData(&elems[0],&elems[elems.size()],idsToSend); + MEDCouplingPointSet *send_mesh=static_cast(field->getField()->buildSubMeshData(&elems[0],&elems[elems.size()],idsToSend)); + if(sourceOrTarget) + matrix.keepTracksOfSourceIds(procId,idsToSend);//Case#1 in Step2 of main algorithm. + else + matrix.keepTracksOfTargetIds(procId,idsToSend);//Case#0 in Step2 of main algorithm. sendMesh(procId,send_mesh,idsToSend); send_mesh->decrRef(); idsToSend->decrRef(); diff --git a/src/ParaMEDMEM/OverlapElementLocator.hxx b/src/ParaMEDMEM/OverlapElementLocator.hxx index 4490be609..754ab6e7c 100644 --- a/src/ParaMEDMEM/OverlapElementLocator.hxx +++ b/src/ParaMEDMEM/OverlapElementLocator.hxx @@ -35,15 +35,15 @@ namespace ParaMEDMEM class ParaFIELD; class ProcessorGroup; class ParaSUPPORT; - class InterpolationMatrix; - + class OverlapInterpolationMatrix; + class OverlapElementLocator : public INTERP_KERNEL::InterpolationOptions { public: OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup& group); virtual ~OverlapElementLocator(); const MPI_Comm *getCommunicator() const; - void exchangeMeshes(); + void exchangeMeshes(OverlapInterpolationMatrix& matrix); std::vector< std::pair > getToDoList() const { return _to_do_list; } std::vector< std::vector< int > > getProcsInInteraction() const { return _proc_pairs; } std::string getSourceMethod() const; @@ -55,7 +55,7 @@ namespace ParaMEDMEM private: void computeBoundingBoxes(); bool intersectsBoundingBox(int i, int j) const; - void sendLocalMeshTo(int procId, bool sourceOrTarget) const; + void sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const; void receiveRemoteMesh(int procId, bool sourceOrTarget); void sendMesh(int procId, const MEDCouplingPointSet *mesh, const DataArrayInt *idsToSend) const; void receiveMesh(int procId, MEDCouplingPointSet* &mesh, DataArrayInt *&ids) const; diff --git a/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx b/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx index 38da7fe04..edc3f3e0e 100644 --- a/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx +++ b/src/ParaMEDMEM/OverlapInterpolationMatrix.cxx @@ -61,6 +61,16 @@ namespace ParaMEDMEM _target_volume.resize(nbelems); } + void OverlapInterpolationMatrix::keepTracksOfSourceIds(int procId, DataArrayInt *ids) + { + _mapping.keepTracksOfSourceIds(procId,ids); + } + + void OverlapInterpolationMatrix::keepTracksOfTargetIds(int procId, DataArrayInt *ids) + { + _mapping.keepTracksOfTargetIds(procId,ids); + } + OverlapInterpolationMatrix::~OverlapInterpolationMatrix() { } @@ -68,56 +78,56 @@ namespace ParaMEDMEM void OverlapInterpolationMatrix::addContribution(const MEDCouplingPointSet *src, const DataArrayInt *srcIds, const std::string& srcMeth, int srcProcId, const MEDCouplingPointSet *trg, const DataArrayInt *trgIds, const std::string& trgMeth, int trgProcId) { - std::string interpMethod(trgMeth); - interpMethod+=srcMeth; + std::string interpMethod(srcMeth); + interpMethod+=trgMeth; //creating the interpolator structure vector > surfaces; int colSize=0; //computation of the intersection volumes between source and target elements const MEDCouplingUMesh *trgC=dynamic_cast(trg); const MEDCouplingUMesh *srcC=dynamic_cast(src); - if ( trg->getMeshDimension() == -1 ) + if ( src->getMeshDimension() == -1 ) { - if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==2) + if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==2) { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(srcC); + MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(trgC); INTERP_KERNEL::Interpolation2D interpolation(*this); - colSize=interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,surfaces,trgMeth.c_str()); } - else if(srcC->getMeshDimension()==3 && srcC->getSpaceDimension()==3) + else if(trgC->getMeshDimension()==3 && trgC->getSpaceDimension()==3) { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(srcC); + MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(trgC); INTERP_KERNEL::Interpolation3D interpolation(*this); - colSize=interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,surfaces,trgMeth.c_str()); } - else if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==3) + else if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==3) { - MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(srcC); + MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(trgC); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - colSize=interpolation.fromIntegralUniform(source_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.fromIntegralUniform(target_mesh_wrapper,surfaces,trgMeth.c_str()); } else throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); } - else if ( srcC->getMeshDimension() == -1 ) + else if ( trg->getMeshDimension() == -1 ) { - if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==2) + if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==2) { - MEDCouplingNormalizedUnstructuredMesh<2,2> distant_mesh_wrapper(trgC); + MEDCouplingNormalizedUnstructuredMesh<2,2> local_mesh_wrapper(srcC); INTERP_KERNEL::Interpolation2D interpolation(*this); - colSize=interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.toIntegralUniform(local_mesh_wrapper,surfaces,srcMeth.c_str()); } - else if(trgC->getMeshDimension()==3 && trgC->getSpaceDimension()==3) + else if(srcC->getMeshDimension()==3 && srcC->getSpaceDimension()==3) { - MEDCouplingNormalizedUnstructuredMesh<3,3> distant_mesh_wrapper(trgC); + MEDCouplingNormalizedUnstructuredMesh<3,3> local_mesh_wrapper(srcC); INTERP_KERNEL::Interpolation3D interpolation(*this); - colSize=interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.toIntegralUniform(local_mesh_wrapper,surfaces,srcMeth.c_str()); } - else if(trgC->getMeshDimension()==2 && trgC->getSpaceDimension()==3) + else if(srcC->getMeshDimension()==2 && srcC->getSpaceDimension()==3) { - MEDCouplingNormalizedUnstructuredMesh<3,2> distant_mesh_wrapper(trgC); + MEDCouplingNormalizedUnstructuredMesh<3,2> local_mesh_wrapper(srcC); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - colSize=interpolation.toIntegralUniform(distant_mesh_wrapper,surfaces,srcMeth.c_str()); + colSize=interpolation.toIntegralUniform(local_mesh_wrapper,surfaces,srcMeth.c_str()); } else throw INTERP_KERNEL::Exception("No para interpolation available for the given mesh and space dimension of distant mesh to -1D sourceMesh"); @@ -126,14 +136,14 @@ namespace ParaMEDMEM { throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); } - else if( trg->getMeshDimension() == 1 - && trg->getSpaceDimension() == 1 ) + else if( src->getMeshDimension() == 1 + && src->getSpaceDimension() == 1 ) { MEDCouplingNormalizedUnstructuredMesh<1,1> target_wrapper(trgC); MEDCouplingNormalizedUnstructuredMesh<1,1> source_wrapper(srcC); INTERP_KERNEL::Interpolation1D interpolation(*this); - colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + colSize=interpolation.interpolateMeshes(source_wrapper,target_wrapper,surfaces,interpMethod.c_str()); target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } @@ -144,7 +154,7 @@ namespace ParaMEDMEM MEDCouplingNormalizedUnstructuredMesh<2,1> source_wrapper(srcC); INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + colSize=interpolation.interpolateMeshes(source_wrapper,target_wrapper,surfaces,interpMethod.c_str()); target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } @@ -155,7 +165,7 @@ namespace ParaMEDMEM MEDCouplingNormalizedUnstructuredMesh<3,2> source_wrapper(srcC); INTERP_KERNEL::Interpolation3DSurf interpolator (*this); - colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,surfaces,interpMethod.c_str()); target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } @@ -166,7 +176,7 @@ namespace ParaMEDMEM MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(srcC); INTERP_KERNEL::Interpolation2D interpolator (*this); - colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,surfaces,interpMethod.c_str()); target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } @@ -177,7 +187,7 @@ namespace ParaMEDMEM MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(srcC); INTERP_KERNEL::Interpolation3D interpolator (*this); - colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + colSize=interpolator.interpolateMeshes(source_wrapper,target_wrapper,surfaces,interpMethod.c_str()); target_wrapper.releaseTempArrays(); source_wrapper.releaseTempArrays(); } @@ -185,57 +195,25 @@ namespace ParaMEDMEM { throw INTERP_KERNEL::Exception("no interpolator exists for these mesh and space dimensions "); } - bool needTargetSurf=isSurfaceComputationNeeded(trgMeth); - MEDCouplingFieldDouble *target_triangle_surf=0; - if(needTargetSurf) - target_triangle_surf=trg->getMeasureField(getMeasureAbsStatus()); + bool needSourceSurf=isSurfaceComputationNeeded(srcMeth); + MEDCouplingFieldDouble *source_triangle_surf=0; + if(needSourceSurf) + source_triangle_surf=src->getMeasureField(getMeasureAbsStatus()); // fillDistributedMatrix(surfaces,srcIds,srcProcId,trgIds,trgProcId); // - if(needTargetSurf) - target_triangle_surf->decrRef(); + if(needSourceSurf) + source_triangle_surf->decrRef(); } /*! - * \b WARNING : res rows refers to source and column (first param of map) to target. + * \b res rows refers to target and column (first param of map) to source. */ void OverlapInterpolationMatrix::fillDistributedMatrix(const std::vector< std::map >& res, const DataArrayInt *srcIds, int srcProc, const DataArrayInt *trgIds, int trgProc) { - //computing matrix with real ids for target - int sz=res.size(); - std::vector< std::map > res1(sz); - const int *trgIds2=0; - int nbTrgIds=_target_field->getField()->getNumberOfTuplesExpected(); - INTERP_KERNEL::AutoPtr tmp2=new int[nbTrgIds]; - if(trgIds) - trgIds2=trgIds->getConstPointer(); - else - { - trgIds2=tmp2; - for(int i=0;i& m=res1[i]; - const std::map& ref=res[i]; - for(std::map::const_iterator it=ref.begin();it!=ref.end();it++) - { - m[(*it).first]=(*it).second; //if(trgIds2) m[trgIds2[(*it).first]]=(*it).second; - } - } - //dealing source ids - if(srcIds) - _mapping.addContributionST(res1,srcIds->getConstPointer(),trgIds2,nbTrgIds,srcProc,trgProc); - else - { - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - for(int i=0;i >& procsInInteraction) { if(_source_support) - _mapping.prepare(procsInInteraction,_source_field->getField()->getNumberOfTuplesExpected()); + _mapping.prepare(procsInInteraction,_target_field->getField()->getNumberOfTuplesExpected()); else _mapping.prepare(procsInInteraction,0); } void OverlapInterpolationMatrix::computeDeno() { - if(_source_field->getField()->getNature()==IntegralGlobConstraint) - _mapping.computeDenoGlobConstraint(); + if(_target_field->getField()->getNature()==ConservativeVolumic) + _mapping.computeDenoConservativeVolumic(_target_field->getField()->getNumberOfTuplesExpected()); + else + throw INTERP_KERNEL::Exception("Policy Not implemented yet : only ConservativeVolumic defined !"); + } + + void OverlapInterpolationMatrix::multiply() + { + _mapping.multiply(_source_field->getField(),_target_field->getField()); } void OverlapInterpolationMatrix::transposeMultiply() diff --git a/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx b/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx index bd11b01ee..eca4e8c32 100644 --- a/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx +++ b/src/ParaMEDMEM/OverlapInterpolationMatrix.hxx @@ -41,6 +41,10 @@ namespace ParaMEDMEM const DECOptions& dec_opt, const InterpolationOptions& i_opt); + void keepTracksOfSourceIds(int procId, DataArrayInt *ids); + + void keepTracksOfTargetIds(int procId, DataArrayInt *ids); + void addContribution(const MEDCouplingPointSet *src, const DataArrayInt *srcIds, const std::string& srcMeth, int srcProcId, const MEDCouplingPointSet *trg, const DataArrayInt *trgIds, const std::string& trgMeth, int trgProcId); @@ -48,6 +52,8 @@ namespace ParaMEDMEM void computeDeno(); + void multiply(); + void transposeMultiply(); virtual ~OverlapInterpolationMatrix(); diff --git a/src/ParaMEDMEM/OverlapMapping.cxx b/src/ParaMEDMEM/OverlapMapping.cxx index 2f7fc4db5..dfc078c0e 100644 --- a/src/ParaMEDMEM/OverlapMapping.cxx +++ b/src/ParaMEDMEM/OverlapMapping.cxx @@ -35,20 +35,52 @@ OverlapMapping::OverlapMapping(const ProcessorGroup& group):_group(group) } /*! - * This method stores from a matrix in format Source(rows)/Target(cols) for a source procId 'srcProcId' and for a target procId 'trgProcId'. + * This method keeps tracks of source ids to know in step 6 of main algorithm, which tuple ids to send away. + * This method incarnates item#1 of step2 algorithm. + */ +void OverlapMapping::keepTracksOfSourceIds(int procId, DataArrayInt *ids) +{ + ids->incrRef(); + _src_ids_st2.push_back(ids); + _src_proc_st2.push_back(procId); +} + +/*! + * This method keeps tracks of target ids to know in step 6 of main algorithm. + * This method incarnates item#0 of step2 algorithm. + */ +void OverlapMapping::keepTracksOfTargetIds(int procId, DataArrayInt *ids) +{ + ids->incrRef(); + _trg_ids_st2.push_back(ids); + _trg_proc_st2.push_back(procId); +} + +/*! + * This method stores from a matrix in format Target(rows)/Source(cols) for a source procId 'srcProcId' and for a target procId 'trgProcId'. * All ids (source and target) are in format of local ids. */ -void OverlapMapping::addContributionST(const std::vector< std::map >& matrixST, const int *srcIds, const int *trgIds, int trgIdsLgth, int srcProcId, int trgProcId) +void OverlapMapping::addContributionST(const std::vector< std::map >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId) { int nbOfRows=matrixST.size(); _matrixes_st.push_back(matrixST); - _source_ids_st.resize(_source_ids_st.size()+1); - _source_ids_st.back().insert(_source_ids_st.back().end(),srcIds,srcIds+nbOfRows); _source_proc_id_st.push_back(srcProcId); - // - _target_ids_st.resize(_target_ids_st.size()+1); - _target_ids_st.back().insert(_target_ids_st.back().end(),trgIds,trgIds+trgIdsLgth); _target_proc_id_st.push_back(trgProcId); + if(srcIds) + {//item#1 of step2 algorithm in proc m. Only to know in advanced nb of recv ids [ (0,1) computed on proc1 and Matrix-Vector on proc1 ] + _nb_of_src_ids_proc_st2.push_back(srcIds->getNumberOfTuples()); + _src_ids_proc_st2.push_back(srcProcId); + } + else + {//item#0 of step2 algorithm in proc k + std::set s; + for(std::vector< std::map >::const_iterator it1=matrixST.begin();it1!=matrixST.end();it1++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + s.insert((*it2).first); + _src_ids_zip_st2.resize(_src_ids_zip_st2.size()+1); + _src_ids_zip_st2.back().insert(_src_ids_zip_st2.back().end(),s.begin(),s.end()); + _src_ids_zip_proc_st2.push_back(trgProcId); + } } /*! @@ -56,10 +88,9 @@ void OverlapMapping::addContributionST(const std::vector< std::map > * In 'procsInInteraction' for a proc with id i, is in interaction with procs listed in procsInInteraction[i]. * * This method is in charge to send matrixes in AlltoAll mode. - * After the call of this method 'this' contains the matrixST for all source elements of the current proc and - * matrixTS for all target elements of current proc. + * After the call of this method 'this' contains the matrixST for all source elements of the current proc */ -void OverlapMapping::prepare(const std::vector< std::vector >& procsInInteraction, int nbOfSrcElems) +void OverlapMapping::prepare(const std::vector< std::vector >& procsInInteraction, int nbOfTrgElems) { CommInterface commInterface=_group.getCommInterface(); const MPIProcessorGroup *group=static_cast(&_group); @@ -70,11 +101,15 @@ void OverlapMapping::prepare(const std::vector< std::vector >& procsInInter INTERP_KERNEL::AutoPtr nbsend3=new int[grpSize]; std::fill(nbsend,nbsend+grpSize,0); int myProcId=_group.myRank(); + _proc_ids_to_recv_vector_st.clear(); + int curProc=0; + for(std::vector< std::vector >::const_iterator it1=procsInInteraction.begin();it1!=procsInInteraction.end();it1++,curProc++) + if(std::find((*it1).begin(),(*it1).end(),myProcId)!=(*it1).end()) + _proc_ids_to_recv_vector_st.push_back(curProc); + _proc_ids_to_send_vector_st=procsInInteraction[myProcId]; for(std::size_t i=0;i<_matrixes_st.size();i++) - { - if(_source_proc_id_st[i]!=myProcId) - nbsend[_source_proc_id_st[i]]=_matrixes_st[i].size(); - } + if(_source_proc_id_st[i]==myProcId) + nbsend[_target_proc_id_st[i]]=_matrixes_st[i].size(); INTERP_KERNEL::AutoPtr nbrecv=new int[grpSize]; commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm); //exchanging matrix @@ -90,7 +125,7 @@ void OverlapMapping::prepare(const std::vector< std::vector >& procsInInter INTERP_KERNEL::AutoPtr bigArrRecv=new int[nbrecv2[grpSize-1]+nbrecv1[grpSize-1]]; commInterface.allToAllV(bigArr,nbsend2,nbsend3,MPI_INT, bigArrRecv,nbrecv1,nbrecv2,MPI_INT, - *comm);// sending ids off sparse matrix (n+1 elems) + src ids (n elems) + *comm);// sending ids of sparse matrix (n+1 elems) //second phase echange target ids std::fill(nbsend2,nbsend2+grpSize,0); INTERP_KERNEL::AutoPtr nbrecv3=new int[grpSize]; @@ -110,12 +145,13 @@ void OverlapMapping::prepare(const std::vector< std::vector >& procsInInter bigArrDRecv2,nbrecv3,nbrecv4,MPI_DOUBLE, *comm); //finishing - unserializationST(nbOfSrcElems,nbrecv,bigArrRecv,nbrecv1,nbrecv2, + unserializationST(nbOfTrgElems,nbrecv,bigArrRecv,nbrecv1,nbrecv2, bigArrRecv2,bigArrDRecv2,nbrecv3,nbrecv4); - //finish to fill _the_matrix_st and _the_matrix_st_target_proc_id with already in place matrix in _matrixes_st - finishToFillFinalMatrixST(nbOfSrcElems); - //exchanging target ids for future sending - prepareIdsToSendST(); + //updating _src_ids_zip_st2 and _src_ids_zip_st2 with received matrix. + updateZipSourceIdsForFuture(); + //finish to fill _the_matrix_st with already in place matrix in _matrixes_st + finishToFillFinalMatrixST(); + //printTheMatrix(); } /*! @@ -143,6 +179,72 @@ void OverlapMapping::computeDenoGlobConstraint() } } +/*! + * Compute denominators. + */ +void OverlapMapping::computeDenoConservativeVolumic(int nbOfTuplesTrg) +{ + CommInterface commInterface=_group.getCommInterface(); + const MPIProcessorGroup *group=static_cast(&_group); + const MPI_Comm *comm=group->getComm(); + int myProcId=_group.myRank(); + // + _the_deno_st.clear(); + std::size_t sz1=_the_matrix_st.size(); + _the_deno_st.resize(sz1); + std::vector deno(nbOfTuplesTrg); + for(std::size_t i=0;i >& mat=_the_matrix_st[i]; + int curSrcId=_the_matrix_st_source_proc_id[i]; + std::vector::iterator isItem1=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId); + int rowId=0; + if(isItem1==_trg_proc_st2.end() || curSrcId==myProcId)//item1 of step2 main algo. Simple, because rowId of mat are directly target ids. + { + for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + deno[rowId]+=(*it2).second; + } + else + {//item0 of step2 main algo. More complicated. + std::vector::iterator fnd=isItem1;//std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId); + int locId=std::distance(_trg_proc_st2.begin(),fnd); + const DataArrayInt *trgIds=_trg_ids_st2[locId]; + const int *trgIds2=trgIds->getConstPointer(); + for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + deno[trgIds2[rowId]]+=(*it2).second; + } + } + // + for(std::size_t i=0;i >& mat=_the_matrix_st[i]; + int curSrcId=_the_matrix_st_source_proc_id[i]; + std::vector::iterator isItem1=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),curSrcId); + std::vector< std::map >& denoM=_the_deno_st[i]; + denoM.resize(mat.size()); + if(isItem1==_trg_proc_st2.end() || curSrcId==myProcId)//item1 of step2 main algo. Simple, because rowId of mat are directly target ids. + { + int rowId=0; + for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + denoM[rowId][(*it2).first]=deno[rowId]; + } + else + { + std::vector::iterator fnd=isItem1; + int locId=std::distance(_trg_proc_st2.begin(),fnd); + const DataArrayInt *trgIds=_trg_ids_st2[locId]; + const int *trgIds2=trgIds->getConstPointer(); + for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++,rowId++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + denoM[rowId][(*it2).first]=deno[trgIds2[rowId]]; + } + } +} + /*! * This method performs step #0/3 in serialization process. * \param count tells specifies nb of elems to send to corresponding proc id. size equal to _group.size(). @@ -158,10 +260,10 @@ void OverlapMapping::serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigAr int myProcId=_group.myRank(); for(std::size_t i=0;i<_matrixes_st.size();i++) { - if(_source_proc_id_st[i]!=myProcId) + if(_source_proc_id_st[i]==myProcId)// && _target_proc_id_st[i]!=myProcId { - count[_source_proc_id_st[i]]=2*_matrixes_st[i].size()+1; - szz+=2*_matrixes_st[i].size()+1; + count[_target_proc_id_st[i]]=_matrixes_st[i].size()+1; + szz+=_matrixes_st[i].size()+1; } } bigArr=new int[szz]; @@ -170,15 +272,14 @@ void OverlapMapping::serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigAr offsets[i]=offsets[i-1]+count[i-1]; for(std::size_t i=0;i<_matrixes_st.size();i++) { - if(_source_proc_id_st[i]!=myProcId) + if(_source_proc_id_st[i]==myProcId) { - int start=offsets[_source_proc_id_st[i]]; + int start=offsets[_target_proc_id_st[i]]; int *work=bigArr+start; *work=0; const std::vector< std::map >& mat=_matrixes_st[i]; for(std::vector< std::map >::const_iterator it=mat.begin();it!=mat.end();it++,work++) work[1]=work[0]+(*it).size(); - std::copy(_source_ids_st[i].begin(),_source_ids_st[i].end(),work+1); } } // @@ -186,7 +287,7 @@ void OverlapMapping::serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigAr for(int i=0;i0) - countForRecv[i]=2*nbOfElemsSrc[i]+1; + countForRecv[i]=nbOfElemsSrc[i]+1; else countForRecv[i]=0; if(i>0) @@ -221,13 +322,13 @@ int OverlapMapping::serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *r int fullLgth=0; for(std::size_t i=0;i<_matrixes_st.size();i++) { - if(_source_proc_id_st[i]!=myProcId) + if(_source_proc_id_st[i]==myProcId) { const std::vector< std::map >& mat=_matrixes_st[i]; int lgthToSend=0; for(std::vector< std::map >::const_iterator it=mat.begin();it!=mat.end();it++) lgthToSend+=(*it).size(); - count[_source_proc_id_st[i]]=lgthToSend; + count[_target_proc_id_st[i]]=lgthToSend; fullLgth+=lgthToSend; } } @@ -240,7 +341,7 @@ int OverlapMapping::serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *r fullLgth=0; for(std::size_t i=0;i<_matrixes_st.size();i++) { - if(_source_proc_id_st[i]!=myProcId) + if(_source_proc_id_st[i]==myProcId) { const std::vector< std::map >& mat=_matrixes_st[i]; for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++) @@ -262,52 +363,35 @@ int OverlapMapping::serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *r * This is the last step after all2Alls for matrix exchange. * _the_matrix_st is the final matrix : * - The first entry is srcId in current proc. - * - The second is the pseudo id of target proc (correspondance with true id is in attribute _the_matrix_st_target_proc_id and _the_matrix_st_target_ids) - * - the third is the trgId in the pseudo target proc + * - The second is the pseudo id of source proc (correspondance with true id is in attribute _the_matrix_st_source_proc_id and _the_matrix_st_source_ids) + * - the third is the srcId in the pseudo source proc */ -void OverlapMapping::unserializationST(int nbOfSrcElems, +void OverlapMapping::unserializationST(int nbOfTrgElems, const int *nbOfElemsSrcPerProc,//first all2all const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs,//2nd all2all const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs)//3rd and 4th all2alls { _the_matrix_st.clear(); - _the_matrix_st.resize(nbOfSrcElems); - _the_matrix_st_target_proc_id.clear(); + _the_matrix_st_source_proc_id.clear(); // int grpSize=_group.size(); for(int i=0;i targetIdsZip;// this zip is to reduce amount of data to send/rexcv on transposeMultiply target ids transfert - for(int k=0;k old2newTrgIds; - int newNbTrg=0; - for(std::set::const_iterator it=targetIdsZip.begin();it!=targetIdsZip.end();it++,newNbTrg++) - old2newTrgIds[*it]=newNbTrg; + _the_matrix_st[j].resize(nbOfElemsSrcPerProc[i]); for(int k=0;k_the_matrix_st_target_ids'. * This method finish the job of filling 'this->_the_matrix_st' and 'this->_the_matrix_st_target_proc_id' by putting candidates in 'this->_matrixes_st' into them. */ -void OverlapMapping::finishToFillFinalMatrixST(int nbOfSrcElems) +void OverlapMapping::finishToFillFinalMatrixST() { int myProcId=_group.myRank(); int sz=_matrixes_st.size(); int nbOfEntryToAdd=0; for(int i=0;i >& mat=_matrixes_st[i]; - const std::vector& srcIds=_source_ids_st[i]; - int sz=srcIds.size();//assert srcIds.size()==mat.size() - for(int k=0;k& m2=mat[k]; - for(std::map::const_iterator it=m2.begin();it!=m2.end();it++) - _the_matrix_st[j][srcIds[k]][(*it).first]=(*it).second; - } - _the_matrix_st_target_ids[j].insert(_the_matrix_st_target_ids[j].end(),_target_ids_st[i].begin(),_target_ids_st[i].end()); + _the_matrix_st[j]=mat; + _the_matrix_st_source_proc_id.push_back(_source_proc_id_st[i]); j++; } + _matrixes_st.clear(); } /*! @@ -364,12 +436,12 @@ void OverlapMapping::prepareIdsToSendST() const MPIProcessorGroup *group=static_cast(&_group); const MPI_Comm *comm=group->getComm(); int grpSize=_group.size(); - _target_ids_to_send_st.clear(); - _target_ids_to_send_st.resize(grpSize); + _source_ids_to_send_st.clear(); + _source_ids_to_send_st.resize(grpSize); INTERP_KERNEL::AutoPtr nbsend=new int[grpSize]; std::fill(nbsend,nbsend+grpSize,0); - for(std::size_t i=0;i<_the_matrix_st_target_proc_id.size();i++) - nbsend[_the_matrix_st_target_proc_id[i]]=_the_matrix_st_target_ids[i].size(); + for(std::size_t i=0;i<_the_matrix_st_source_proc_id.size();i++) + nbsend[_the_matrix_st_source_proc_id[i]]=_the_matrix_st_source_ids[i].size(); INTERP_KERNEL::AutoPtr nbrecv=new int[grpSize]; commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm); // @@ -381,10 +453,10 @@ void OverlapMapping::prepareIdsToSendST() nbsend3[i]=nbsend3[i-1]+nbsend2[i-1]; int sendSz=nbsend3[grpSize-1]+nbsend2[grpSize-1]; INTERP_KERNEL::AutoPtr bigDataSend=new int[sendSz]; - for(std::size_t i=0;i<_the_matrix_st_target_proc_id.size();i++) + for(std::size_t i=0;i<_the_matrix_st_source_proc_id.size();i++) { - int offset=nbsend3[_the_matrix_st_target_proc_id[i]]; - std::copy(_the_matrix_st_target_ids[i].begin(),_the_matrix_st_target_ids[i].end(),((int *)nbsend3)+offset); + int offset=nbsend3[_the_matrix_st_source_proc_id[i]]; + std::copy(_the_matrix_st_source_ids[i].begin(),_the_matrix_st_source_ids[i].end(),((int *)nbsend3)+offset); } INTERP_KERNEL::AutoPtr nbrecv2=new int[grpSize]; INTERP_KERNEL::AutoPtr nbrecv3=new int[grpSize]; @@ -402,109 +474,205 @@ void OverlapMapping::prepareIdsToSendST() { if(nbrecv2[i]>0) { - _target_ids_to_send_st[i].insert(_target_ids_to_send_st[i].end(),((int *)bigDataRecv)+nbrecv3[i],((int *)bigDataRecv)+nbrecv3[i]+nbrecv2[i]); + _source_ids_to_send_st[i].insert(_source_ids_to_send_st[i].end(),((int *)bigDataRecv)+nbrecv3[i],((int *)bigDataRecv)+nbrecv3[i]+nbrecv2[i]); } } } /*! * This method performs a transpose multiply of 'fieldInput' and put the result into 'fieldOutput'. - * 'fieldInput' is expected to be the targetfield and 'fieldOutput' the sourcefield. + * 'fieldInput' is expected to be the sourcefield and 'fieldOutput' the targetfield. */ -void OverlapMapping::transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) +void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) const { -#if 0 - CommInterface commInterface=_group.getCommInterface(); - const MPIProcessorGroup *group=static_cast(&_group); - const MPI_Comm *comm=group->getComm(); - int grpSize=_group.size(); - INTERP_KERNEL::AutoPtr nbsend=new int[grpSize]; - std::fill(nbsend,nbsend+grpSize,0); - for(std::size_t i=0;i<_the_matrix_st.size();i++) - nbsend[_the_matrix_st_target_proc_id[i]]=_the_matrix_st_target_ids[i].size(); - INTERP_KERNEL::AutoPtr nbrecv=new int[grpSize]; - commInterface.allToAll(nbsend,1,MPI_INT,nbrecv,1,MPI_INT,*comm); - int nbOfCompo=fieldInput->getNumberOfComponents();//to improve same number of components - std::transform((int *)nbsend,(int *)nbsend+grpSize,(int *)nbsend,std::bind2nd(std::multiplies(),nbOfCompo)); - std::transform((int *)nbrecv,(int *)nbrecv+grpSize,(int *)nbrecv,std::bind2nd(std::multiplies(),nbOfCompo)); - INTERP_KERNEL::AutoPtr nbsend2=new int[grpSize]; - nbsend2[0]=0; - for(int i=1;i nbsend3=new double[szToSend]; - double *work=nbsend3; - for(std::size_t i=0;i<_the_matrix_st.size();i++) - { - MEDCouplingAutoRefCountObjectPtr ptr=fieldInput->getArray()->selectByTupleId(&_target_ids_st[i][0],&(_target_ids_st[i][0])+_target_ids_st[i].size()); - std::copy(ptr->getConstPointer(),ptr->getConstPointer()+nbsend[_target_proc_id_st[i]],work+nbsend2[_target_proc_id_st[i]]); - } - INTERP_KERNEL::AutoPtr nbrecv3=new int[grpSize]; - nbrecv3[0]=0; - for(int i=1;i nbrecv2=new double[szToFetch]; -#endif - // int nbOfCompo=fieldInput->getNumberOfComponents();//to improve same number of components to test CommInterface commInterface=_group.getCommInterface(); const MPIProcessorGroup *group=static_cast(&_group); const MPI_Comm *comm=group->getComm(); int grpSize=_group.size(); + int myProcId=_group.myRank(); // INTERP_KERNEL::AutoPtr nbsend=new int[grpSize]; - std::fill(nbsend,nbsend+grpSize,0); INTERP_KERNEL::AutoPtr nbsend2=new int[grpSize]; - for(int i=0;i nbsend3=new double[szToSend]; INTERP_KERNEL::AutoPtr nbrecv=new int[grpSize]; - INTERP_KERNEL::AutoPtr nbrecv3=new int[grpSize]; + INTERP_KERNEL::AutoPtr nbrecv2=new int[grpSize]; + std::fill(nbsend,nbsend+grpSize,0); std::fill(nbrecv,nbrecv+grpSize,0); - for(std::size_t i=0;i<_the_matrix_st_target_proc_id.size();i++) - nbrecv[_the_matrix_st_target_proc_id[i]]=_the_matrix_st_target_ids[i].size()*nbOfCompo; - nbrecv3[0]=0; - for(int i=1;i valsToSend; for(int i=0;i ptr=fieldInput->getArray()->selectByTupleId(&(_target_ids_to_send_st[i][0]), - &(_target_ids_to_send_st[i][0])+_target_ids_to_send_st[i].size()); - std::copy(ptr->getConstPointer(),ptr->getConstPointer()+nbsend[i],work+nbsend2[i]); + if(std::find(_proc_ids_to_send_vector_st.begin(),_proc_ids_to_send_vector_st.end(),i)!=_proc_ids_to_send_vector_st.end()) + { + std::vector::const_iterator isItem1=std::find(_src_proc_st2.begin(),_src_proc_st2.end(),i); + MEDCouplingAutoRefCountObjectPtr vals; + if(isItem1!=_src_proc_st2.end())//item1 of step2 main algo + { + int id=std::distance(_src_proc_st2.begin(),isItem1); + vals=fieldInput->getArray()->selectByTupleId(_src_ids_st2[id]->getConstPointer(),_src_ids_st2[id]->getConstPointer()+_src_ids_st2[id]->getNumberOfTuples()); + } + else + {//item0 of step2 main algo + int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i)); + vals=fieldInput->getArray()->selectByTupleId(&(_src_ids_zip_st2[id])[0],&(_src_ids_zip_st2[id])[0]+_src_ids_zip_st2[id].size()); + } + nbsend[i]=vals->getNbOfElems(); + valsToSend.insert(valsToSend.end(),vals->getConstPointer(),vals->getConstPointer()+nbsend[i]); + } + if(std::find(_proc_ids_to_recv_vector_st.begin(),_proc_ids_to_recv_vector_st.end(),i)!=_proc_ids_to_recv_vector_st.end()) + { + std::vector::const_iterator isItem0=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i); + if(isItem0==_trg_proc_st2.end())//item1 of step2 main algo [ (0,1) computed on proc1 and Matrix-Vector on proc1 ] + { + std::vector::const_iterator it1=std::find(_src_ids_proc_st2.begin(),_src_ids_proc_st2.end(),i); + if(it1!=_src_ids_proc_st2.end()) + { + int id=std::distance(_src_ids_proc_st2.begin(),it1); + nbrecv[i]=_nb_of_src_ids_proc_st2[id]*nbOfCompo; + } + else if(i==myProcId) + { + nbrecv[i]=fieldInput->getNumberOfTuplesExpected()*nbOfCompo; + } + else + throw INTERP_KERNEL::Exception("Plouff ! send email to anthony.geay@cea.fr ! "); + } + else + {//item0 of step2 main algo [ (2,1) computed on proc2 but Matrix-Vector on proc1 ] [(1,0) computed on proc1 but Matrix-Vector on proc0] + int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i)); + nbrecv[i]=_src_ids_zip_st2[id].size()*nbOfCompo; + } + } } - INTERP_KERNEL::AutoPtr nbrecv2=new double[szToRecv]; - commInterface.allToAllV(nbsend3,nbsend,nbsend2,MPI_DOUBLE, - nbrecv2,nbrecv,nbrecv3,MPI_DOUBLE, - *comm); - // deserialization + for(int i=1;i bigArr=new double[nbrecv2[grpSize-1]+nbrecv[grpSize-1]]; + commInterface.allToAllV(&valsToSend[0],nbsend,nbsend2,MPI_DOUBLE, + bigArr,nbrecv,nbrecv2,MPI_DOUBLE,*comm); fieldOutput->getArray()->fillWithZero(); - INTERP_KERNEL::AutoPtr workZone=new double[nbOfCompo]; - for(std::size_t i=0;i<_the_matrix_st.size();i++) + INTERP_KERNEL::AutoPtr tmp=new double[nbOfCompo]; + for(int i=0;igetArray()->getPointer(); - int targetProcId=_the_matrix_st_target_proc_id[i]; - const std::vector >& m=_the_matrix_st[i]; - const std::vector >& deno=_the_deno_st[i]; - const double *vecOnTargetProcId=((const double *)nbrecv2)+nbrecv3[targetProcId]; - std::size_t nbOfIds=m.size(); - for(std::size_t j=0;j0) { - const std::map& m2=m[j]; - const std::map& deno2=deno[j]; - for(std::map::const_iterator it=m2.begin();it!=m2.end();it++) + double *pt=fieldOutput->getArray()->getPointer(); + std::vector::const_iterator it=std::find(_the_matrix_st_source_proc_id.begin(),_the_matrix_st_source_proc_id.end(),i); + if(it==_the_matrix_st_source_proc_id.end()) + throw INTERP_KERNEL::Exception("Big problem !"); + int id=std::distance(_the_matrix_st_source_proc_id.begin(),it); + const std::vector< std::map >& mat=_the_matrix_st[id]; + const std::vector< std::map >& deno=_the_deno_st[id]; + std::vector::const_iterator isItem0=std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i); + if(isItem0==_trg_proc_st2.end())//item1 of step2 main algo [ (0,1) computed on proc1 and Matrix-Vector on proc1 ] { - std::map::const_iterator it2=deno2.find((*it).first); - std::transform(vecOnTargetProcId+((*it).first*nbOfCompo),vecOnTargetProcId+((*it).first+1)*nbOfCompo,(double *)workZone,std::bind2nd(std::multiplies(),(*it).second)); - std::transform((double *)workZone,(double *)workZone+nbOfCompo,(double *)workZone,std::bind2nd(std::multiplies(),1./(*it2).second)); - std::transform((double *)workZone,(double *)workZone+nbOfCompo,res,res,std::plus()); + int nbOfTrgTuples=mat.size(); + for(int j=0;j& mat1=mat[j]; + const std::map& deno1=deno[j]; + std::map::const_iterator it4=deno1.begin(); + for(std::map::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it4++) + { + std::transform(bigArr+nbrecv2[i]+((*it3).first)*nbOfCompo,bigArr+nbrecv2[i]+((*it3).first+1)*(nbOfCompo),(double *)tmp,std::bind2nd(std::multiplies(),(*it3).second/(*it4).second)); + std::transform((double *)tmp,(double *)tmp+nbOfCompo,pt,pt,std::plus()); + } + } + } + else + {//item0 of step2 main algo [ (2,1) computed on proc2 but Matrix-Vector on proc1 ] + double *pt=fieldOutput->getArray()->getPointer(); + std::map zipCor; + int id=std::distance(_src_ids_zip_proc_st2.begin(),std::find(_src_ids_zip_proc_st2.begin(),_src_ids_zip_proc_st2.end(),i)); + const std::vector zipIds=_src_ids_zip_st2[id]; + int newId=0; + for(std::vector::const_iterator it=zipIds.begin();it!=zipIds.end();it++,newId++) + zipCor[*it]=newId; + int id2=std::distance(_trg_proc_st2.begin(),std::find(_trg_proc_st2.begin(),_trg_proc_st2.end(),i)); + const DataArrayInt *tgrIds=_trg_ids_st2[id2]; + const int *tgrIds2=tgrIds->getConstPointer(); + int nbOfTrgTuples=mat.size(); + for(int j=0;j& mat1=mat[j]; + const std::map& deno1=deno[j]; + std::map::const_iterator it5=deno1.begin(); + for(std::map::const_iterator it3=mat1.begin();it3!=mat1.end();it3++,it5++) + { + std::map::const_iterator it4=zipCor.find((*it3).first); + if(it4==zipCor.end()) + throw INTERP_KERNEL::Exception("Hmmmmm send e mail to anthony.geay@cea.fr !"); + std::transform(bigArr+nbrecv2[i]+((*it4).second)*nbOfCompo,bigArr+nbrecv2[i]+((*it4).second+1)*(nbOfCompo),(double *)tmp,std::bind2nd(std::multiplies(),(*it3).second/(*it5).second)); + std::transform((double *)tmp,(double *)tmp+nbOfCompo,pt+tgrIds2[j]*nbOfCompo,pt+tgrIds2[j]*nbOfCompo,std::plus()); + } + } } } } } + +/*! + * This method performs a transpose multiply of 'fieldInput' and put the result into 'fieldOutput'. + * 'fieldInput' is expected to be the targetfield and 'fieldOutput' the sourcefield. + */ +void OverlapMapping::transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) +{ +} + +/*! + * This method should be called immediately after _the_matrix_st has been filled with remote computed matrix put in this proc for Matrix-Vector. + * This method computes for these matrix the minimal set of source ids corresponding to the source proc id. + */ +void OverlapMapping::updateZipSourceIdsForFuture() +{ + CommInterface commInterface=_group.getCommInterface(); + const MPIProcessorGroup *group=static_cast(&_group); + const MPI_Comm *comm=group->getComm(); + int grpSize=_group.size(); + int myProcId=_group.myRank(); + int nbOfMatrixRecveived=_the_matrix_st_source_proc_id.size(); + for(int i=0;i >& mat=_the_matrix_st[i]; + _src_ids_zip_proc_st2.push_back(curSrcProcId); + _src_ids_zip_st2.resize(_src_ids_zip_st2.size()+1); + std::set s; + for(std::vector< std::map >::const_iterator it1=mat.begin();it1!=mat.end();it1++) + for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + s.insert((*it2).first); + _src_ids_zip_st2.back().insert(_src_ids_zip_st2.back().end(),s.begin(),s.end()); + } + } +} + +// #include + +// void OverlapMapping::printTheMatrix() const +// { +// CommInterface commInterface=_group.getCommInterface(); +// const MPIProcessorGroup *group=static_cast(&_group); +// const MPI_Comm *comm=group->getComm(); +// int grpSize=_group.size(); +// int myProcId=_group.myRank(); +// std::cerr << "I am proc #" << myProcId << std::endl; +// int nbOfMat=_the_matrix_st.size(); +// std::cerr << "I do manage " << nbOfMat << "matrix : "<< std::endl; +// for(int i=0;i >& locMat=_the_matrix_st[i]; +// for(std::vector< std::map >::const_iterator it1=locMat.begin();it1!=locMat.end();it1++) +// { +// for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) +// std::cerr << "(" << (*it2).first << "," << (*it2).second << "), "; +// std::cerr << std::endl; +// } +// } +// std::cerr << "*********" << std::endl; +// } diff --git a/src/ParaMEDMEM/OverlapMapping.hxx b/src/ParaMEDMEM/OverlapMapping.hxx index 79248a1f8..3ac4abdb6 100644 --- a/src/ParaMEDMEM/OverlapMapping.hxx +++ b/src/ParaMEDMEM/OverlapMapping.hxx @@ -20,22 +20,29 @@ #ifndef __OVERLAPMAPPING_HXX__ #define __OVERLAPMAPPING_HXX__ +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + #include #include namespace ParaMEDMEM { class ProcessorGroup; + class DataArrayInt; class MEDCouplingFieldDouble; class OverlapMapping { public: OverlapMapping(const ProcessorGroup& group); - void addContributionST(const std::vector< std::map >& matrixST, const int *srcIds, const int *trgIds, int trgIdsLgth, int srcProcId, int trgProcId); - void prepare(const std::vector< std::vector >& procsInInteraction, int nbOfSrcElems); + void keepTracksOfSourceIds(int procId, DataArrayInt *ids); + void keepTracksOfTargetIds(int procId, DataArrayInt *ids); + void addContributionST(const std::vector< std::map >& matrixST, const DataArrayInt *srcIds, int srcProcId, const DataArrayInt *trgIds, int trgProcId); + void prepare(const std::vector< std::vector >& procsInInteraction, int nbOfTrgElems); + void computeDenoConservativeVolumic(int nbOfTuplesTrg); void computeDenoGlobConstraint(); // + void multiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput) const; void transposeMultiply(const MEDCouplingFieldDouble *fieldInput, MEDCouplingFieldDouble *fieldOutput); private: void serializeMatrixStep0ST(const int *nbOfElemsSrc, int *&bigArr, int *count, int *offsets, @@ -43,12 +50,23 @@ namespace ParaMEDMEM int serializeMatrixStep1ST(const int *nbOfElemsSrc, const int *recvStep0, const int *countStep0, const int *offsStep0, int *&bigArrI, double *&bigArrD, int *count, int *offsets, int *countForRecv, int *offsForRecv) const; - void unserializationST(int nbOfSrcElems, const int *nbOfElemsSrcPerProc, const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs, + void unserializationST(int nbOfTrgElems, const int *nbOfElemsSrcPerProc, const int *bigArrRecv, const int *bigArrRecvCounts, const int *bigArrRecvOffs, const int *bigArrRecv2, const double *bigArrDRecv2, const int *bigArrRecv2Count, const int *bigArrRecv2Offs); - void finishToFillFinalMatrixST(int nbOfSrcElems); + void finishToFillFinalMatrixST(); void prepareIdsToSendST(); + void updateZipSourceIdsForFuture(); + //void printTheMatrix() const; private: const ProcessorGroup &_group; + //! vector of ids + std::vector< MEDCouplingAutoRefCountObjectPtr > _src_ids_st2;//item #1 + std::vector< int > _src_proc_st2;//item #1 + std::vector< MEDCouplingAutoRefCountObjectPtr > _trg_ids_st2;//item #0 + std::vector< int > _trg_proc_st2;//item #0 + std::vector< int > _nb_of_src_ids_proc_st2;//item #1 + std::vector< int > _src_ids_proc_st2;//item #1 + std::vector< std::vector > _src_ids_zip_st2;//same size as _src_ids_zip_proc_st2. Sorted. specifies for each id the corresponding ids to send. This is for item0 of Step2 of main algorithm + std::vector< int > _src_ids_zip_proc_st2; //! vector of matrixes the first entry correspond to source proc id in _source_ids_st std::vector< std::vector< std::map > > _matrixes_st; std::vector< std::vector > _source_ids_st; @@ -57,11 +75,14 @@ namespace ParaMEDMEM std::vector< int > _target_proc_id_st; //! the matrix for matrix-vector product. The first dimension the set of target procs that interacts with local source mesh. The second dimension correspond to nb of local source ids. std::vector< std::vector< std::map > > _the_matrix_st; - std::vector< int > _the_matrix_st_target_proc_id; - std::vector< std::vector > _the_matrix_st_target_ids; + std::vector< int > _the_matrix_st_source_proc_id; + std::vector< std::vector > _the_matrix_st_source_ids; std::vector< std::vector< std::map > > _the_deno_st; - //! this attribute is of size _group.size(); for each procId in _group _target_ids_to_send_st[procId] contains tupleId to send abroad - std::vector< std::vector > _target_ids_to_send_st; + //! this attribute stores the proc ids that wait for data from this proc ids for matrix-vector computation + std::vector< int > _proc_ids_to_send_vector_st; + std::vector< int > _proc_ids_to_recv_vector_st; + //! this attribute is of size _group.size(); for each procId in _group _source_ids_to_send_st[procId] contains tupleId to send abroad + std::vector< std::vector > _source_ids_to_send_st; }; } diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx index 05a0b3275..ea2128b5f 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx @@ -47,7 +47,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0); CPPUNIT_TEST(testInterpKernelDECPartialProcs); CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox); - //CPPUNIT_TEST(testOverlapDEC1); + CPPUNIT_TEST(testOverlapDEC1); CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D); CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx index b0b216137..67af2e297 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx @@ -34,7 +34,7 @@ using namespace ParaMEDMEM; void ParaMEDMEMTest::testMEDLoaderRead1() { - string fileName=getResourceFile("pointe_import22.med"); + string fileName=getResourceFile("pointe.med"); vector meshNames=MEDLoader::GetMeshNames(fileName.c_str()); CPPUNIT_ASSERT_EQUAL(1,(int)meshNames.size()); MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(fileName.c_str(),meshNames[0].c_str(),0); @@ -176,11 +176,11 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT(fieldsNameNode[1]=="fieldnodeint"); std::vector > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsNameNode[0].c_str()); CPPUNIT_ASSERT_EQUAL(3,(int)its0Node.size()); - CPPUNIT_ASSERT_EQUAL(1,its0Node[0].first); + CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].first); CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].second); - CPPUNIT_ASSERT_EQUAL(2,its0Node[1].first); + CPPUNIT_ASSERT_EQUAL(1,its0Node[1].first); CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second); - CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].first);//strange but like that + CPPUNIT_ASSERT_EQUAL(2,its0Node[2].first); CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].second); MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); field0Nodes->checkCoherency(); @@ -196,7 +196,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT(constMesh); field0Nodes->decrRef(); // - field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[1].first,its0Node[1].second); + field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second); field0Nodes->checkCoherency(); CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); @@ -224,7 +224,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12); field0Nodes->decrRef(); // - field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second); + field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); field0Nodes->checkCoherency(); CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx index ba9360979..5a41497be 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx @@ -81,7 +81,7 @@ void ParaMEDMEMTest::testOverlapDEC1() ParaMEDMEM::ComponentTopology comptopo; parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh"); parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo); - parafieldS->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint);//ConservativeVolumic + parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsS=parafieldS->getField()->getArray()->getPointer(); valsS[0]=7.; valsS[1]=8.; // @@ -98,7 +98,7 @@ void ParaMEDMEMTest::testOverlapDEC1() meshT->finishInsertingCells(); parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh"); parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo); - parafieldT->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint);//ConservativeVolumic + parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsT=parafieldT->getField()->getArray()->getPointer(); valsT[0]=7.; } @@ -122,7 +122,7 @@ void ParaMEDMEMTest::testOverlapDEC1() ParaMEDMEM::ComponentTopology comptopo; parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh"); parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo); - parafieldS->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint);//ConservativeVolumic + parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsS=parafieldS->getField()->getArray()->getPointer(); valsS[0]=9.; valsS[1]=11.; // @@ -139,7 +139,7 @@ void ParaMEDMEMTest::testOverlapDEC1() meshT->finishInsertingCells(); parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh"); parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo); - parafieldT->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint); + parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsT=parafieldT->getField()->getArray()->getPointer(); valsT[0]=8.; } @@ -162,7 +162,7 @@ void ParaMEDMEMTest::testOverlapDEC1() ParaMEDMEM::ComponentTopology comptopo; parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh"); parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo); - parafieldS->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint);//ConservativeVolumic + parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsS=parafieldS->getField()->getArray()->getPointer(); valsS[0]=10.; // @@ -179,29 +179,27 @@ void ParaMEDMEMTest::testOverlapDEC1() meshT->finishInsertingCells(); parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh"); parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo); - parafieldT->getField()->setNature(ParaMEDMEM::IntegralGlobConstraint); + parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint double *valsT=parafieldT->getField()->getArray()->getPointer(); valsT[0]=9.; } dec.attachSourceLocalField(parafieldS); dec.attachTargetLocalField(parafieldT); dec.synchronize(); - dec.sendRecvData(false); + dec.sendRecvData(true); // - /*if(rank==0) + if(rank==0) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.5,parafieldS->getField()->getArray()->getIJ(0,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,parafieldS->getField()->getArray()->getIJ(0,1),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.75,parafieldT->getField()->getArray()->getIJ(0,0),1e-12); } if(rank==1) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,parafieldS->getField()->getArray()->getIJ(0,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,parafieldS->getField()->getArray()->getIJ(0,1),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,parafieldT->getField()->getArray()->getIJ(0,0),1e-12); } if(rank==2) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,parafieldS->getField()->getArray()->getIJ(0,0),1e-12); - }*/ + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.5,parafieldT->getField()->getArray()->getIJ(0,0),1e-12); + } delete parafieldS; delete parafieldT; delete parameshS; diff --git a/src/RENUMBER/renumbering.cxx b/src/RENUMBER/renumbering.cxx index c06003951..66224da7d 100644 --- a/src/RENUMBER/renumbering.cxx +++ b/src/RENUMBER/renumbering.cxx @@ -29,8 +29,8 @@ #include "MEDMEM_Connectivity.hxx" #include "MEDMEM_Field.hxx" #include "MEDMEM_DriversDef.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMeshDriver22.hxx" +#include "MEDMEM_MedFileBrowser.hxx" +#include "MEDMEM_MedMeshDriver.hxx" #include "RenumberingFactory.hxx" @@ -46,9 +46,9 @@ void computeNeighbour(const MESH* mesh,const medGeometryElement& Type, vector
  • calculateFullDescendingConnectivity(MED_CELL); const int* rev_conn=mesh->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); const int* rev_conn_index=mesh->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - int nb_face= mesh->getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS); - int nb_edge = mesh->getNumberOfElementsWithPoly(MED_EDGE,MED_ALL_ELEMENTS); - nb_cell= mesh->getNumberOfElementsWithPoly(MED_CELL,Type); + int nb_face= mesh->getNumberOfElements(MED_FACE,MEDMEM_ALL_ELEMENTS); + int nb_edge = mesh->getNumberOfElements(MED_EDGE,MEDMEM_ALL_ELEMENTS); + nb_cell= mesh->getNumberOfElements(MED_CELL,Type); int nb_constituent; if(mesh->getMeshDimension()==2) @@ -79,7 +79,7 @@ void computeNeighbour(const MESH* mesh,const medGeometryElement& Type, vector
  • & iperm) { - if(Type==MED_POLYHEDRA) + /*if(Type==MED_POLYHEDRA) { int *conn_face_index_init=(int*)mesh.getPolyhedronFacesIndex(); int *conn_index_init=(int*)mesh.getPolyhedronIndex(MED_FULL_INTERLACE); @@ -144,9 +144,9 @@ void changeConnectivity(MESH& mesh, const medGeometryElement& Type, const int& n delete[] conn_renum; delete[] conn_index_renum; } - else + else*/ { - const int *conn_init=mesh.getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,Type); + const int *conn_init=mesh.getConnectivity(MED_NODAL,MED_CELL,Type); const int *conn_index_init=mesh.getConnectivityIndex(MED_NODAL,MED_CELL); int *conn_renum=new int[conn_index_init[nb_cell]-1]; int *conn_index_renum=new int[nb_cell+1]; @@ -166,7 +166,7 @@ void changeConnectivity(MESH& mesh, const medGeometryElement& Type, const int& n } CONNECTIVITY* myConnectivity=(CONNECTIVITY*)mesh.getConnectivityptr(); - myConnectivity->setNodal(conn_renum,MED_CELL,Type); + myConnectivity->setNodal(conn_renum,MED_CELL,Type,conn_index_renum); delete[] conn_renum; delete[] conn_index_renum; } @@ -213,9 +213,9 @@ int main (int argc, char** argv) system(s.c_str()); // Reading file structure - const MED med_struct (MED_DRIVER,filename_in); + const MEDFILEBROWSER med_struct(filename_in); int nb_mesh, nb_fields; - deque mesh_names,f_names; + vector mesh_names,f_names; nb_mesh=med_struct.getNumberOfMeshes(); nb_fields=med_struct.getNumberOfFields(); mesh_names=med_struct.getMeshNames(); @@ -237,15 +237,14 @@ int main (int argc, char** argv) int nb_fields_tot=0; for (int ifield = 0; ifield < nb_fields; ifield++) { - deque dtit=med_struct.getFieldIteration(f_names[ifield]); - for (deque::const_iterator iter =dtit.begin(); iter!=dtit.end(); iter++) + vector dtit=med_struct.getFieldIteration(f_names[ifield]); + for (vector::const_iterator iter =dtit.begin(); iter!=dtit.end(); iter++) { field_names.push_back(f_names[ifield]); iternumber.push_back(iter->dt); ordernumber.push_back(iter->it); ++nb_fields_tot; - FIELD_* field = med_struct.getField(f_names[ifield],iter->dt,iter->it); - if (dynamic_cast*>(field)) + if(med_struct.getFieldType(f_names[ifield])==MED_EN::MED_REEL64) types.push_back(1); else types.push_back(0); @@ -257,20 +256,19 @@ int main (int argc, char** argv) // Reading mesh MESH myMesh; myMesh.setName(meshname); - MED_MESH_RDONLY_DRIVER22 *drv22=new MED_MESH_RDONLY_DRIVER22(filename_in,&myMesh); + MED_MESH_RDONLY_DRIVER *drv22=new MED_MESH_RDONLY_DRIVER(filename_in,&myMesh); drv22->desactivateFacesComputation(); int newDrv=myMesh.addDriver(*drv22); delete drv22; myMesh.read(newDrv); - int nb_type=myMesh.getNumberOfTypesWithPoly(MED_CELL); + int nb_type=myMesh.getNumberOfTypes(MED_CELL); if (nb_type!=1) { cout << "Mesh must have only one type of cell" << endl; return -1; } - medGeometryElement *Types = myMesh.getTypesWithPoly(MED_CELL); + const medGeometryElement *Types = myMesh.getTypes(MED_CELL); medGeometryElement Type=Types[0]; - delete[] Types; t_read_mesh=clock(); MESH* workMesh=new MESH(myMesh); diff --git a/src/RENUMBER/testRenumbering.py b/src/RENUMBER/testRenumbering.py index b4978697b..8d1363ca3 100755 --- a/src/RENUMBER/testRenumbering.py +++ b/src/RENUMBER/testRenumbering.py @@ -61,20 +61,14 @@ for i in range(9): field=field&(f.getValueIJ(i+1,2)==field_ini[i*2+1]) f.rmDriver(id) -nbcell2dboost=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell2dboost=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[2,6,13,11,11,13,14,12,6,5,15,13,12,14,10,4,13,15,16,14,5,1,7,15,14,16,9,10,15,7,8,16,16,8,3,9] connectivite_index=[1,5,9,13,17,21,25,29,33,37] -conn=m.getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_QUAD4) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_QUAD4) conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); -conn2dboost=(len(conn)==len(connectivite)) -if conn2dboost: - for i in range(0,len(connectivite)): - conn2dboost=conn2dboost&(conn[i]==connectivite[i]) -conn_index2dboost=(len(conn_index)==len(connectivite_index)) -if conn_index2dboost: - for i in range(0,len(connectivite_index)): - conn_index2dboost=conn_index2dboost&(conn_index[i]==connectivite_index[i]) -Boost2D=conn2dboost&conn_index2dboost&(nbcell2dboost==9)&field +conn2dboost=(list(conn)==connectivite) # convert numpy.ndarray to list +conn_index2dboost=(list(conn_index)==connectivite_index) +Boost2D=conn2dboost and conn_index2dboost and (nbcell2dboost==9) and field os.remove(dir_mesh+"/out_"+filename) @@ -83,20 +77,14 @@ method="METIS" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell2dmetis=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell2dmetis=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[12,14,10,4,2,6,13,11,11,13,14,12,16,8,3,9,5,1,7,15,15,7,8,16,14,16,9,10,6,5,15,13,13,15,16,14] connectivite_index=[1,5,9,13,17,21,25,29,33,37] -conn=m.getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_QUAD4) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_QUAD4) conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); -conn2dmetis=(len(conn)==len(connectivite)) -if conn2dmetis: - for i in range(0,len(connectivite)): - conn2dmetis=conn2dmetis&(conn[i]==connectivite[i]) -conn_index2dmetis=(len(conn_index)==len(connectivite_index)) -if conn_index2dmetis: - for i in range(0,len(connectivite_index)): - conn_index2dmetis=conn_index2dmetis&(conn_index[i]==connectivite_index[i]) -Metis2D=conn2dmetis&conn_index2dmetis&(nbcell2dmetis==9) +conn2dmetis=(list(conn)==connectivite) +conn_index2dmetis=(list(conn_index)==connectivite_index) +Metis2D=conn2dmetis and conn_index2dmetis and (nbcell2dmetis==9) os.remove(dir_mesh+"/out_"+filename) ## *** Avec polygone *** @@ -110,20 +98,14 @@ method="BOOST" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell2dpolyboost=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell2dpolyboost=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[2,5,9,10,11,10,9,12,5,6,8,9,4,11,12,16,12,9,8,13,6,1,7,8,16,12,13,15,13,8,7,14,15,13,14,3] connectivite_index=[1,5,9,13,17,21,25,29,33,37] -conn=m.getPolygonsConnectivity(MED_FULL_INTERLACE,MED_CELL) -conn_index=m.getPolygonsConnectivityIndex(MED_FULL_INTERLACE,MED_CELL); -conn2dpolyboost=(len(conn)==len(connectivite)) -if conn2dpolyboost: - for i in range(0,len(connectivite)): - conn2dpolyboost=conn2dpolyboost&(conn[i]==connectivite[i]) -conn_index2dpolyboost=(len(conn_index)==len(connectivite_index)) -if conn_index2dpolyboost: - for i in range(0,len(connectivite_index)): - conn_index2dpolyboost=conn_index2dpolyboost&(conn_index[i]==connectivite_index[i]) -PolyBoost2D=conn2dpolyboost&conn_index2dpolyboost&(nbcell2dpolyboost==9) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_POLYGON) +conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL) +conn2dpolyboost=(list(conn)==connectivite) +conn_index2dpolyboost=(list(conn_index)==connectivite_index) +PolyBoost2D=conn2dpolyboost and conn_index2dpolyboost and (nbcell2dpolyboost==9) os.remove(dir_mesh+"/out_"+filename) print "TEST 2D Metis with polygons" @@ -131,20 +113,14 @@ method="METIS" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell2dpolymetis=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell2dpolymetis=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[6,1,7,8,2,5,9,10,5,6,8,9,15,13,14,3,4,11,12,16,16,12,13,15,11,10,9,12,12,9,8,13,13,8,7,14] connectivite_index=[1,5,9,13,17,21,25,29,33,37] -conn=m.getPolygonsConnectivity(MED_FULL_INTERLACE,MED_CELL) -conn_index=m.getPolygonsConnectivityIndex(MED_FULL_INTERLACE,MED_CELL); -conn2dpolymetis=(len(conn)==len(connectivite)) -if conn2dpolymetis: - for i in range(0,len(connectivite)): - conn2dpolymetis=conn2dpolymetis&(conn[i]==connectivite[i]) -conn_index2dpolymetis=(len(conn_index)==len(connectivite_index)) -if conn_index2dpolymetis: - for i in range(0,len(connectivite_index)): - conn_index2dpolymetis=conn_index2dpolymetis&(conn_index[i]==connectivite_index[i]) -PolyMetis2D=conn2dpolymetis&conn_index2dpolymetis&(nbcell2dpolymetis==9) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_POLYGON) +conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL) +conn2dpolymetis=(list(conn)==connectivite) +conn_index2dpolymetis=(list(conn_index)==connectivite_index) +PolyMetis2D=conn2dpolymetis and conn_index2dpolymetis and (nbcell2dpolymetis==9) os.remove(dir_mesh+"/out_"+filename) @@ -162,20 +138,14 @@ method="BOOST" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell3dboost=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell3dboost=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[23,13,5,18,27,22,14,26,17,6,13,23,25,16,22,27,27,22,14,26,24,15,7,20,9,23,18,1,21,27,26,10,25,16,22,27,19,8,15,24,2,17,23,9,12,25,27,21,21,27,26,10,11,24,20,3,12,25,27,21,4,19,24,11] connectivite_index=[1,9,17,25,33,41,49,57,65] -conn=m.getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_HEXA8) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_HEXA8) conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); -conn3dboost=(len(conn)==len(connectivite)) -if conn3dboost: - for i in range(0,len(connectivite)): - conn3dboost=conn3dboost&(conn[i]==connectivite[i]) -conn_index3dboost=(len(conn_index)==len(connectivite_index)) -if conn_index3dboost: - for i in range(0,len(connectivite_index)): - conn_index3dboost=conn_index3dboost&(conn_index[i]==connectivite_index[i]) -Boost3D=conn3dboost&conn_index3dboost&(nbcell3dboost==8) +conn3dboost=(list(conn)==connectivite) +conn_index3dboost=(list(conn_index)==connectivite_index) +Boost3D=conn3dboost and conn_index3dboost and (nbcell3dboost==8) os.remove(dir_mesh+"/out_"+filename) @@ -184,19 +154,13 @@ method="METIS" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell3dmetis=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) +nbcell3dmetis=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) connectivite=[12,25,27,21,4,19,24,11,27,22,14,26,24,15,7,20,17,6,13,23,25,16,22,27,9,23,18,1,21,27,26,10,23,13,5,18,27,22,14,26,25,16,22,27,19,8,15,24,2,17,23,9,12,25,27,21,21,27,26,10,11,24,20,3] connectivite_index=[1,9,17,25,33,41,49,57,65] -conn=m.getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_HEXA8) +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_HEXA8) conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); -conn3dmetis=(len(conn)==len(connectivite)) -if conn3dmetis: - for i in range(0,len(connectivite)): - conn3dmetis=conn3dmetis&(conn[i]==connectivite[i]) -conn_index3dmetis=(len(conn_index)==len(connectivite_index)) -if conn_index3dmetis: - for i in range(0,len(connectivite_index)): - conn_index3dmetis=conn_index3dmetis&(conn_index[i]==connectivite_index[i]) +conn3dmetis=(list(conn)==connectivite) +conn_index3dmetis=(list(conn_index)==connectivite_index) Metis3D=conn3dmetis&conn_index3dmetis&(nbcell3dmetis==8) os.remove(dir_mesh+"/out_"+filename) @@ -222,26 +186,21 @@ method="BOOST" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell3dpolyboost=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) -connectivite=[23,13,5,18,27,26,14,22,23,27,22,13,13,22,14,5,5,14,26,18,18,26,27,23,17,6,13,23,25,27,22,16,17,25,16,6,6,16,22,13,13,22,27,23,23,27,25,17,27,22,14,26,24,20,7,15,27,24,15,22,22,15,7,14,14,7,20,26,26,20,24,27,9,23,18,1,21,10,26,27,9,21,27,23,23,27,26,18,18,26,10,1,1,10,21,9,25,16,22,27,19,24,15,8,25,19,8,16,16,8,15,22,22,15,24,27,27,24,19,25,2,17,23,9,12,21,27,25,2,12,25,17,17,25,27,23,23,27,21,9,9,21,12,2,21,27,26,10,11,3,20,24,21,11,24,27,27,24,20,26,26,20,3,10,10,3,11,21,12,25,27,21,4,11,24,19,12,4,19,25,25,19,24,27,27,24,11,21,21,11,4,12] -connectivite_face_index=[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193] -connectivite_index=[1,7,13,19,25,31,37,43,49] -conn=m.getPolyhedronConnectivity(MED_FULL_INTERLACE) -conn_index=m.getPolyhedronIndex(MED_FULL_INTERLACE) -conn_face_index=m.getPolyhedronFacesIndex() -conn3dpolyboost=(len(conn)==len(connectivite)) -if conn3dpolyboost: - for i in range(0,len(connectivite)): - conn3dpolyboost=conn3dpolyboost&(conn[i]==connectivite[i]) -conn_index3dpolyboost=(len(conn_index)==len(connectivite_index)) -if conn3dpolyboost: - for i in range(0,len(connectivite_index)): - conn_index3dpolyboost=conn_index3dpolyboost&(conn_index[i]==connectivite_index[i]) -conn_face_index3dpolyboost=(len(conn_face_index)==len(connectivite_face_index)) -if conn_face_index3dpolyboost: - for i in range(0,len(connectivite_face_index)): - conn_face_index3dpolyboost=conn_face_index3dpolyboost&(conn_face_index[i]==connectivite_face_index[i]) -PolyBoost3D=conn3dpolyboost&conn_index3dpolyboost&conn_face_index3dpolyboost&(nbcell3dpolyboost==8) +nbcell3dpolyboost=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) +connectivite=[23,13,5,18,-1,27,26,14,22,-1,23,27,22,13,-1,13,22,14,5,-1,5,14,26,18,-1,18,26,27,23, + 17,6,13,23,-1,25,27,22,16,-1,17,25,16,6,-1,6,16,22,13,-1,13,22,27,23,-1,23,27,25,17, + 27,22,14,26,-1,24,20,7,15,-1,27,24,15,22,-1,22,15,7,14,-1,14,7,20,26,-1,26,20,24,27, + 9,23,18,1,-1,21,10,26,27,-1,9,21,27,23,-1,23,27,26,18,-1,18,26,10,1,-1,1,10,21,9, + 25,16,22,27,-1,19,24,15,8,-1,25,19,8,16,-1,16,8,15,22,-1,22,15,24,27,-1,27,24,19,25, + 2,17,23,9,-1,12,21,27,25,-1,2,12,25,17,-1,17,25,27,23,-1,23,27,21,9,-1,9,21,12,2, + 21,27,26,10,-1,11,3,20,24,-1,21,11,24,27,-1,27,24,20,26,-1,26,20,3,10,-1,10,3,11,21, + 12,25,27,21,-1,4,11,24,19,-1,12,4,19,25,-1,25,19,24,27,-1,27,24,11,21,-1,21,11,4,12] +connectivite_index=[1, 30, 59, 88, 117, 146, 175, 204, 233] +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_POLYHEDRA) +conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); +conn3dpolyboost=(connectivite==list(conn)) +conn_index3dpolyboost=(connectivite_index==list(conn_index)) +PolyBoost3D=(conn3dpolyboost and conn_index3dpolyboost and (nbcell3dpolyboost==8)) os.remove(dir_mesh+"/out_"+filename) @@ -250,26 +209,21 @@ method="METIS" string_to_execute="'"+dir_renumber+" "+dir_mesh+"/"+filename+" "+meshname+" "+method+" "+dir_mesh+"/out_"+filename+"'" eval("os.system("+string_to_execute+")") m = MESH(MED_DRIVER,dir_mesh+"/out_"+filename,meshname) -nbcell3dpolymetis=m.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) -connectivite=[12,25,27,21,4,11,24,19,12,4,19,25,25,19,24,27,27,24,11,21,21,11,4,12,27,22,14,26,24,20,7,15,27,24,15,22,22,15,7,14,14,7,20,26,26,20,24,27,17,6,13,23,25,27,22,16,17,25,16,6,6,16,22,13,13,22,27,23,23,27,25,17,9,23,18,1,21,10,26,27,9,21,27,23,23,27,26,18,18,26,10,1,1,10,21,9,23,13,5,18,27,26,14,22,23,27,22,13,13,22,14,5,5,14,26,18,18,26,27,23,25,16,22,27,19,24,15,8,25,19,8,16,16,8,15,22,22,15,24,27,27,24,19,25,2,17,23,9,12,21,27,25,2,12,25,17,17,25,27,23,23,27,21,9,9,21,12,2,21,27,26,10,11,3,20,24,21,11,24,27,27,24,20,26,26,20,3,10,10,3,11,21] -connectivite_face_index=[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193] -connectivite_index=[1,7,13,19,25,31,37,43,49] -conn=m.getPolyhedronConnectivity(MED_FULL_INTERLACE) -conn_index=m.getPolyhedronIndex(MED_FULL_INTERLACE) -conn_face_index=m.getPolyhedronFacesIndex() -conn3dpolymetis=(len(conn)==len(connectivite)) -conn_index3dpolymetis=(len(conn_index)==len(connectivite_index)) -conn_face_index3dpolymetis=(len(conn_face_index)==len(connectivite_face_index)) -if conn3dpolymetis: - for i in range(0,len(connectivite)): - conn3dpolymetis=conn3dpolymetis&(conn[i]==connectivite[i]) -if conn_index3dpolymetis: - for i in range(0,len(connectivite_index)): - conn_index3dpolymetis=conn_index3dpolymetis&(conn_index[i]==connectivite_index[i]) -if conn_face_index3dpolymetis: - for i in range(0,len(connectivite_face_index)): - conn_face_index3dpolymetis=conn_face_index3dpolymetis&(conn_face_index[i]==connectivite_face_index[i]) -PolyMetis3D=conn3dpolymetis&conn_index3dpolymetis&conn_face_index3dpolymetis&(nbcell3dpolymetis==8) +nbcell3dpolymetis=m.getNumberOfElements(MED_CELL,MEDMEM_ALL_ELEMENTS) +connectivite=[12,25,27,21,-1,4,11,24,19,-1,12,4,19,25,-1,25,19,24,27,-1,27,24,11,21,-1,21,11,4,12, + 27,22,14,26,-1,24,20,7,15,-1,27,24,15,22,-1,22,15,7,14,-1,14,7,20,26,-1,26,20,24,27, + 17,6,13,23,-1,25,27,22,16,-1,17,25,16,6,-1,6,16,22,13,-1,13,22,27,23,-1,23,27,25,17, + 9,23,18,1,-1,21,10,26,27,-1,9,21,27,23,-1,23,27,26,18,-1,18,26,10,1,-1,1,10,21,9, + 23,13,5,18,-1,27,26,14,22,-1,23,27,22,13,-1,13,22,14,5,-1,5,14,26,18,-1,18,26,27,23, + 25,16,22,27,-1,19,24,15,8,-1,25,19,8,16,-1,16,8,15,22,-1,22,15,24,27,-1,27,24,19,25, + 2,17,23,9,-1,12,21,27,25,-1,2,12,25,17,-1,17,25,27,23,-1,23,27,21,9,-1,9,21,12,2, + 21,27,26,10,-1,11,3,20,24,-1,21,11,24,27,-1,27,24,20,26,-1,26,20,3,10,-1,10,3,11,21] +connectivite_index=[1, 30, 59, 88, 117, 146, 175, 204, 233] +conn=m.getConnectivity(MED_NODAL,MED_CELL,MEDMEM_POLYHEDRA) +conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); +conn3dpolymetis=(list(conn)==connectivite) +conn_index3dpolymetis=(list(conn_index)==connectivite_index) +PolyMetis3D=(conn3dpolymetis and conn_index3dpolymetis and (nbcell3dpolymetis==8)) os.remove(dir_mesh+"/out_"+filename) -- 2.39.2