From: vsr Date: Mon, 10 Jun 2013 12:54:19 +0000 (+0000) Subject: Merge from V6_main (dev of Anthony GEAY) 10/06/2013 X-Git-Tag: V6_7_0~12 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=02ec14131ec8e7ba69f7024936f8a846a3061319;p=tools%2Fmedcoupling.git Merge from V6_main (dev of Anthony GEAY) 10/06/2013 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 02c36b2e8..b57b33ff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,9 @@ SET(VERSION "6.6.0") SET(VERSION_DEV "0") SET(WITH_MEDMEMGUI "0") +#Defining all options first +option(SALOME_USE_MPI "Use MPI containers" OFF) + SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR}) IF(KERNEL_ROOT_DIR) FILE(TO_CMAKE_PATH $ENV{KERNEL_ROOT_DIR} KERNEL_ROOT_DIR) @@ -36,37 +39,41 @@ IF(KERNEL_ROOT_DIR) SET(SALOME_MACROS_DIR ${KERNEL_ROOT_DIR}/salome_adm/cmake_files) INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindPLATFORM.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindPYTHON.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindMPI.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindOMNIORB.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindPTHREADS.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindHDF5.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindBOOST.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindLIBXML2.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindSWIG.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindPYTHON.cmake) + if(SALOME_USE_MPI) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindMPI.cmake) + endif(SALOME_USE_MPI) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindOMNIORB.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindPTHREADS.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindHDF5.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindBOOST.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindLIBXML2.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindSWIG.cmake) INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindCPPUNIT.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindDOXYGEN.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindDOXYGEN.cmake) INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindSPHINX.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindLIBBATCH.cmake) - INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindKERNEL.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/FindSalomeLIBBATCH.cmake) + INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/FindKERNEL.cmake) SET(GUI_ROOT_DIR $ENV{GUI_ROOT_DIR}) FILE(TO_CMAKE_PATH $ENV{GUI_ROOT_DIR} GUI_ROOT_DIR) IF(GUI_ROOT_DIR) SET(MED_ENABLE_GUI ON) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindCAS.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindQT4.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindOPENGL.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindVTK.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindQWT.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindSIPPYQT.cmake) - INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/FindGUI.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindCAS.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindQT4.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindOPENGL.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindVTK.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindQWT.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindSIPPYQT.cmake) + INCLUDE(${GUI_ROOT_DIR}/adm_local/cmake_files/deprecated/FindGUI.cmake) ENDIF(GUI_ROOT_DIR) ELSE(KERNEL_ROOT_DIR) SET(SALOME_MACROS_DIR ${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files) INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindPLATFORM.cmake) - INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindMPI.cmake) + if(SALOME_USE_MPI) + INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindMPI.cmake) + endif(SALOME_USE_MPI) INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindBOOST.cmake) INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindCPPUNIT.cmake) INCLUDE(${CMAKE_SOURCE_DIR}/adm_local_without_kernel/cmake_files/FindHDF5.cmake) diff --git a/adm_local/CMakeLists.txt b/adm_local/CMakeLists.txt index 7d6dfa86e..0b3b48975 100644 --- a/adm_local/CMakeLists.txt +++ b/adm_local/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,4 +17,5 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +ADD_SUBDIRECTORY(unix) ADD_SUBDIRECTORY(cmake_files) diff --git a/adm_local/cmake_files/CMakeLists.txt b/adm_local/cmake_files/CMakeLists.txt index d46c5d67e..15a93f0cf 100644 --- a/adm_local/cmake_files/CMakeLists.txt +++ b/adm_local/cmake_files/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/adm_local/unix/CMakeLists.txt b/adm_local/unix/CMakeLists.txt new file mode 100644 index 000000000..67f329dba --- /dev/null +++ b/adm_local/unix/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +ADD_SUBDIRECTORY(config_files) diff --git a/adm_local/unix/config_files/CMakeLists.txt b/adm_local/unix/config_files/CMakeLists.txt new file mode 100644 index 000000000..71776f10b --- /dev/null +++ b/adm_local/unix/config_files/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SET(dist_admlocalm4_DATA + ac_check_sizeof_fortran.m4 + check_GUI.m4 + check_Med.m4 + check_Med2.m4 + check_med3.m4 + check_bft.m4 + check_fvm.m4 + check_metis.m4 + check_parmetis.m4 + check_scotch.m4 + med_check_sizeof_medint.m4 + renumber.m4 + splitter.m4 + with_Kernel.m4 +) + +FOREACH(f ${dist_admlocalm4_DATA}) + SET(DEST adm_local/unix/config_files) + INSTALL(FILES ${f} DESTINATION ${DEST}) +ENDFOREACH(f ${dist_admlocalm4_DATA}) diff --git a/adm_local/unix/config_files/renumber.m4 b/adm_local/unix/config_files/renumber.m4 index a7a3e59a0..9232649eb 100644 --- a/adm_local/unix/config_files/renumber.m4 +++ b/adm_local/unix/config_files/renumber.m4 @@ -1,4 +1,4 @@ -dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public diff --git a/adm_local_without_kernel/CMakeLists.txt b/adm_local_without_kernel/CMakeLists.txt index 1575c37e7..86c99f919 100755 --- a/adm_local_without_kernel/CMakeLists.txt +++ b/adm_local_without_kernel/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 33af97efd..1da1574f7 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index f3b35dd2f..02d277093 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,7 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -ADD_SUBDIRECTORY(MEDMEM) ADD_SUBDIRECTORY(salome) ADD_SUBDIRECTORY(doxygen) diff --git a/doc/MEDMEM/FIELDcreate.cxx b/doc/MEDMEM/FIELDcreate.cxx index 301a5de4a..749af3517 100644 --- a/doc/MEDMEM/FIELDcreate.cxx +++ b/doc/MEDMEM/FIELDcreate.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/FIELDcreate.py b/doc/MEDMEM/FIELDcreate.py index 79c29b0c8..4ad33dbb9 100644 --- a/doc/MEDMEM/FIELDcreate.py +++ b/doc/MEDMEM/FIELDcreate.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/FIELDgeneral.cxx b/doc/MEDMEM/FIELDgeneral.cxx index a51a55447..265ef8a30 100644 --- a/doc/MEDMEM/FIELDgeneral.cxx +++ b/doc/MEDMEM/FIELDgeneral.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/FIELDgeneral.py b/doc/MEDMEM/FIELDgeneral.py index 7d051bea0..9a932a5d8 100644 --- a/doc/MEDMEM/FIELDgeneral.py +++ b/doc/MEDMEM/FIELDgeneral.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx index a48cfad01..39dfad160 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py index 341816d0d..b776e98c9 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx index ab7bb3cf6..9293b2309 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py index 703f54a66..d92472fd2 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx index 45a3ad195..3d97f0c2c 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py index 01c61fba2..b103a0b85 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHINGexample.cxx b/doc/MEDMEM/MESHINGexample.cxx index 03e9de5f1..45249d5ba 100644 --- a/doc/MEDMEM/MESHINGexample.cxx +++ b/doc/MEDMEM/MESHINGexample.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHINGexample.py b/doc/MEDMEM/MESHINGexample.py index d7db8160c..9d5937c34 100644 --- a/doc/MEDMEM/MESHINGexample.py +++ b/doc/MEDMEM/MESHINGexample.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHconnectivities.cxx b/doc/MEDMEM/MESHconnectivities.cxx index 1f360f818..fdba7e641 100644 --- a/doc/MEDMEM/MESHconnectivities.cxx +++ b/doc/MEDMEM/MESHconnectivities.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHconnectivities.py b/doc/MEDMEM/MESHconnectivities.py index 47a80db41..deb17593a 100644 --- a/doc/MEDMEM/MESHconnectivities.py +++ b/doc/MEDMEM/MESHconnectivities.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHcoordinates.cxx b/doc/MEDMEM/MESHcoordinates.cxx index 1acaaddd0..bd9e24b07 100644 --- a/doc/MEDMEM/MESHcoordinates.cxx +++ b/doc/MEDMEM/MESHcoordinates.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHcoordinates.py b/doc/MEDMEM/MESHcoordinates.py index 013590ff7..8d28a14d0 100644 --- a/doc/MEDMEM/MESHcoordinates.py +++ b/doc/MEDMEM/MESHcoordinates.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHgeneral.cxx b/doc/MEDMEM/MESHgeneral.cxx index 504014ecc..85035cb9c 100644 --- a/doc/MEDMEM/MESHgeneral.cxx +++ b/doc/MEDMEM/MESHgeneral.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/MESHgeneral.py b/doc/MEDMEM/MESHgeneral.py index c60ffc5f8..42a294426 100644 --- a/doc/MEDMEM/MESHgeneral.py +++ b/doc/MEDMEM/MESHgeneral.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/MEDMEM/Makefile.am b/doc/MEDMEM/Makefile.am index f788b6d65..599bed903 100644 --- a/doc/MEDMEM/Makefile.am +++ b/doc/MEDMEM/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/Makefile.am b/doc/Makefile.am index d2117a6b1..4e725ae86 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/doxygen/BuildPyExamplesFromCPP.py b/doc/doxygen/BuildPyExamplesFromCPP.py index 7996588b2..a31ee207d 100644 --- a/doc/doxygen/BuildPyExamplesFromCPP.py +++ b/doc/doxygen/BuildPyExamplesFromCPP.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/doxygen/CMakeLists.txt b/doc/doxygen/CMakeLists.txt index 63e0def07..47161b504 100644 --- a/doc/doxygen/CMakeLists.txt +++ b/doc/doxygen/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in index 7c4a2f768..bbf2c1e57 100644 --- a/doc/doxygen/Doxyfile_med_user.in +++ b/doc/doxygen/Doxyfile_med_user.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -71,6 +71,7 @@ WARN_LOGFILE = log_user #--------------------------------------------------------------------------- INPUT = @builddir@ \ @srcdir@ \ + @srcdir@/fakesources \ @srcdir@/../../src/ParaMEDMEM \ @srcdir@/../../src/INTERP_KERNEL \ @srcdir@/../../src/INTERP_KERNEL/Bases \ @@ -91,7 +92,7 @@ FILE_PATTERNS = MEDMEM_GMesh.* \ OverlapDEC.* \ DEC.* \ DisjointDEC.* \ - MPIProcessorGroup.* \ + MPIProcessorGroup.* \ StructuredCoincidentDEC.* \ ExplicitCoincidentDEC.* \ NonCoincidentDEC.* \ @@ -119,6 +120,8 @@ FILE_PATTERNS = MEDMEM_GMesh.* \ MEDCouplingUMeshDesc.* \ MEDCouplingPointSet.* \ MEDCouplingCMesh.* \ + MEDCouplingStructuredMesh.* \ + MEDCouplingCurveLinearMesh.* \ MEDCouplingExtrudedMesh.* \ MEDCouplingFieldDouble.* \ MEDCouplingField.* \ diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am index 10599e26c..2bef1a876 100644 --- a/doc/doxygen/Makefile.am +++ b/doc/doxygen/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/doxygen/fakesources/MEDCouplingField.C b/doc/doxygen/fakesources/MEDCouplingField.C new file mode 100644 index 000000000..7793773f4 --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingField.C @@ -0,0 +1,56 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// generation of documentation for inline methods. + + +namespace ParaMEDMEM +{ + /*! + * Checks if \a this field is correctly defined, else an exception is thrown. + * \throw If the mesh is not set. + * \throw If the data array is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a this->getTimeTolerance() < 0. + * \throw If the temporal discretization data is incorrect. + * \throw If mesh data does not correspond to field data. + */ + void MEDCouplingField::checkCoherency() const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the underlying mesh of \a this field. + * \return const ParaMEDMEM::MEDCouplingMesh * - a const pointer to the underlying mesh. + */ + const ParaMEDMEM::MEDCouplingMesh *MEDCouplingField::getMesh() const {} + /*! + * Returns the description of \a this field. + * \return const char * - a string containing the field description. + */ + const char *MEDCouplingField::getDescription() const {} + /*! + * Sets the description of \a this field. + * \param [in] desc - a string containing the field description. + */ + void MEDCouplingField::setDescription(const char *desc) {} + /*! + * Returns the name of \a this field. + * \return const char * - a string containing the field name. + */ + const char *MEDCouplingField::getName() const {} +} diff --git a/doc/doxygen/fakesources/MEDCouplingFieldDouble.C b/doc/doxygen/fakesources/MEDCouplingFieldDouble.C new file mode 100644 index 000000000..ee19715ca --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingFieldDouble.C @@ -0,0 +1,394 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods, +// * groupping methods into "Basic API", "Advanced" and "Others..." sections + + +namespace ParaMEDMEM +{ + /*! + * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of + * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] + _other_ [ i, j ] ). + * Number of tuples and components in the two fields must be the same. + * \param [in] other - the input field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of + * \a this and a given field ( _f_ [ i, j ] = _this_ [ i, j ] - _other_ [ i, j ] ). + * Number of tuples and components in the two fields must be the same. + * \param [in] other - the field to subtract from \a this one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing product values of \a this and a + * given field. There are 2 valid cases. + * 1. The fields have same number of tuples and components. Then each value of + * the result field (_f_) is a product of the corresponding values of _this_ and + * _other_, i.e. _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, j ]. + * 2. The fields have same number of tuples and one field, say _other_, has one + * component. Then + * _f_ [ i, j ] = _this_ [ i, j ] * _other_ [ i, 0 ]. + * + * The two fields must have same number of tuples and same underlying mesh. + * \param [in] other - a factor field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not compatible for production (areCompatibleForMul()), + * i.e. they differ not only in values and possibly number of components. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing division of \a this and a given + * field. There are 2 valid cases. + * 1. The fields have same number of tuples and components. Then each value of + * the result field (_f_) is a division of the corresponding values of \a this and + * \a other, i.e. _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, j ]. + * 2. The fields have same number of tuples and _other_ has one component. Then + * _f_ [ i, j ] = _this_ [ i, j ] / _other_ [ i, 0 ]. + * + * \param [in] other - a denominator field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not compatible for division (areCompatibleForDiv()), + * i.e. they differ not only in values and possibly in number of components. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing a dot product of \a this and a given field, + * so that the i-th tuple of the result field (_f_) is a sum of products of j-th components of + * i-th tuples of two fields (\f$ f_i = \sum_ {}^n f1_j * f2_j \f$). + * Number of tuples and components in the two fields must be the same. + * \param [in] other - the input field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing a cross product of \a this and + * a given field, so that the i-th tuple of the result field is a 3D vector which + * is a cross product of two vectors defined by the i-th tuples of the two fields. + * Number of tuples in the fields must be the same. + * Number of components in the fields must be 3. + * \param [in] other - the input field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 3 + * \throw If \a other->getNumberOfComponents() != 3 + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing maximal values of \a this and a + * given field. Number of tuples and components in the two fields must be the same. + * \param [in] other - the field to compare values with \a this one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a new MEDCouplingFieldDouble containing minimal values of \a this and a + * given field. Number of tuples and components in the two fields must be the same. + * \param [in] other - the field to compare values with \a this one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the data array of \a this field. + * \return const DataArrayDouble * - a const pointer to the data array of \a this field. + */ + const DataArrayDouble *MEDCouplingFieldDouble::getArray() const {} + /*! + * Returns the data array of \a this field apt for modification. + * \return DataArrayDouble * - a non-const pointer to the data array of \a this field. + */ + DataArrayDouble *MEDCouplingFieldDouble::getArray() {} + /*! + * Sets a precision used to compare time values. + * \param [in] val - the precision value. + */ + void MEDCouplingFieldDouble::setTimeTolerance(double val) {} + /*! + * Returns a precision used to compare time values. + * \return double - the precision value. + */ + double MEDCouplingFieldDouble::getTimeTolerance() const {} + /*! + * Sets the number of iteration where the data array of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] it - the iteration number. + */ + void MEDCouplingFieldDouble::setIteration(int it) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the number of iteration where the second data array of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] it - the iteration number. + */ + void MEDCouplingFieldDouble::setEndIteration(int it) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the order number of iteration where the data array of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] order - the order number. + */ + void MEDCouplingFieldDouble::setOrder(int order) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the order number of iteration where the second data array of \a this field has + * been calculated. + * \param [in] order - the order number. + */ + void MEDCouplingFieldDouble::setEndOrder(int order) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the time when the data array of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] val - the time value. + */ + void MEDCouplingFieldDouble::setTimeValue(double val) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the time when the second data array of \a this field has been calculated. + * \param [in] val - the time value. + */ + void MEDCouplingFieldDouble::setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets time, number of iteration and order number of iteration when the data array + * of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] val - the time value. + * \param [in] iteration - the iteration number. + * \param [in] order - the order number. + */ + void MEDCouplingFieldDouble::setTime(double val, int iteration, int order) {} + /*! + * Returns time, number of iteration and order number of iteration when the data array + * of \a this field has been calculated. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [out] iteration - the iteration number. + * \param [out] order - the order number. + * \return double - the time value. + */ + double MEDCouplingFieldDouble::getTime(int& iteration, int& order) const {} + /*! + * Returns a value indexed by a tuple id and a component id. + * \param [in] tupleId - the id of the tuple of interest. + * \param [in] compoId - the id of the component of interest. + * \return double - the field value. + */ + double MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const {} +} + +namespace ParaMEDMEM +{ +/*! \name Basic API */ +///@{ +MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::MergeFields(const std::vector& a); +MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); +MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); +MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector& fs); +MEDCouplingFieldDouble::accumulate(double *res) const; +MEDCouplingFieldDouble::accumulate(int compId) const; +MEDCouplingFieldDouble::advancedRepr() const; +MEDCouplingFieldDouble::applyFunc(const char *func); +MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func); +MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func); +MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val); +MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func); +MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func); +MEDCouplingFieldDouble::applyLin(double a, double b, int compoId); +MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; +MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const; +MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const; +MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue=0.); +MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15); +MEDCouplingFieldDouble::checkCoherency() const; +MEDCouplingFieldDouble::clone(bool recDeepCpy) const; +MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const; +MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other); +MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other); +MEDCouplingFieldDouble::crossProduct(const MEDCouplingFieldDouble& other) const; +MEDCouplingFieldDouble::deepCpy() const; +MEDCouplingFieldDouble::determinant() const; +MEDCouplingFieldDouble::deviator() const; +MEDCouplingFieldDouble::dot(const MEDCouplingFieldDouble& other) const; +MEDCouplingFieldDouble::doublyContractedProduct() const; +MEDCouplingFieldDouble::eigenValues() const; +MEDCouplingFieldDouble::eigenVectors() const; +MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func); +MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func); +MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func); +MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const char *func); +MEDCouplingFieldDouble::getArray() const; +MEDCouplingFieldDouble::getArray(); +MEDCouplingFieldDouble::getAverageValue() const; +MEDCouplingFieldDouble::getIJ(int tupleId, int compoId) const; +MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const; +MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const; +MEDCouplingFieldDouble::getMaxValue() const; +MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const; +MEDCouplingFieldDouble::getMinValue() const; +MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const; +MEDCouplingFieldDouble::getNumberOfComponents() const; +MEDCouplingFieldDouble::getNumberOfTuples() const; +MEDCouplingFieldDouble::getNumberOfValues() const; +MEDCouplingFieldDouble::getTime(int& iteration, int& order) const; +MEDCouplingFieldDouble::getTimeDiscretization() const; +MEDCouplingFieldDouble::getTimeTolerance() const; +MEDCouplingFieldDouble::getTimeUnit() const; +MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const; +MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const; +MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const; +MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const; +MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs=true) const; +MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs=true) const; +MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const; +MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const; +MEDCouplingFieldDouble::inverse() const; +MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; +MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const; +MEDCouplingFieldDouble::magnitude() const; +MEDCouplingFieldDouble::max(const MEDCouplingFieldDouble& other) const; +MEDCouplingFieldDouble::maxPerTuple() const; +MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals=1e-15); +MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals=1e-15); +MEDCouplingFieldDouble::min(const MEDCouplingFieldDouble& other) const; +MEDCouplingFieldDouble::norm2() const; +MEDCouplingFieldDouble::normL1(double *res) const; +MEDCouplingFieldDouble::normL1(int compId) const; +MEDCouplingFieldDouble::normL2(double *res) const; +MEDCouplingFieldDouble::normL2(int compId) const; +MEDCouplingFieldDouble::normMax() const; +MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check=true); +MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps=1e-15); +MEDCouplingFieldDouble::setArray(DataArrayDouble *array); +MEDCouplingFieldDouble::setArrays(const std::vector& arrs); +MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array); +MEDCouplingFieldDouble::setEndIteration(int it); +MEDCouplingFieldDouble::setIteration(int it); +MEDCouplingFieldDouble::setNature(NatureOfField nat); +MEDCouplingFieldDouble::setOrder(int order); +MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds); +MEDCouplingFieldDouble::setTime(double val, int iteration, int order); +MEDCouplingFieldDouble::setTimeTolerance(double val); +MEDCouplingFieldDouble::setTimeUnit(const char *unit); +MEDCouplingFieldDouble::setTimeValue(double val); +MEDCouplingFieldDouble::simpleRepr() const; +MEDCouplingFieldDouble::simplexize(int policy); +MEDCouplingFieldDouble::sortPerTuple(bool asc); +MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15); +MEDCouplingFieldDouble::trace() const; +MEDCouplingFieldDouble::updateTime() const; +MEDCouplingFieldDouble::writeVTK(const char *fileName) const; +MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals=1e-15); +MEDCouplingFieldDouble::zipCoords(double epsOnVals=1e-15); + MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator=(double value); + MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator*(const MEDCouplingFieldDouble& other) const; + MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator+(const MEDCouplingFieldDouble& other) const; + MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator-(const MEDCouplingFieldDouble& other) const; + MEDCouplingFieldDouble * MEDCouplingFieldDouble::operator/(const MEDCouplingFieldDouble& other) const; + const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble & MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other); +///@} +/*! \name Advanced API */ +///@{ +MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check=true); +MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); +///@} + +/*! \name Others... */ +///@{ + MEDCouplingFieldDouble::negate() const; + MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const; + MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other); + MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); +MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const; +MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); +MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); +MEDCouplingFieldDouble::applyFuncFast32(const char *func); +MEDCouplingFieldDouble::applyFuncFast64(const char *func); +MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const; +MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; +MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const; +MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const; +MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const; +MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other); +MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const; +MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); +MEDCouplingFieldDouble::getArrays() const; +MEDCouplingFieldDouble::getEndArray() const; +MEDCouplingFieldDouble::getEndArray(); +MEDCouplingFieldDouble::getEndTime(int& iteration, int& order) const; +MEDCouplingFieldDouble::getHeapMemorySize() const; +MEDCouplingFieldDouble::getStartTime(int& iteration, int& order) const; +MEDCouplingFieldDouble::getTimeDiscretizationUnderGround() const; +MEDCouplingFieldDouble::getTimeDiscretizationUnderGround(); +MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfo) const; +MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const; +MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const; +MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; +MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const; +MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays); +MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const; +MEDCouplingFieldDouble::setEndOrder(int order); +MEDCouplingFieldDouble::setEndTime(double val, int iteration, int order); +MEDCouplingFieldDouble::setEndTimeValue(double val); +MEDCouplingFieldDouble::setStartTime(double val, int iteration, int order); +MEDCouplingFieldDouble::synchronizeTimeWithMesh(); +MEDCouplingFieldDouble::synchronizeTimeWithSupport(); +MEDCouplingFieldDouble::~MEDCouplingFieldDouble(); +MEDCouplingFieldDouble::_time_discr; +///@} +} diff --git a/doc/doxygen/fakesources/MEDCouplingMemArray.C b/doc/doxygen/fakesources/MEDCouplingMemArray.C new file mode 100644 index 000000000..1756efd3a --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingMemArray.C @@ -0,0 +1,610 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods of DataArray* classes +// * groupping methods into "Basic API", "Advanced" and "Others..." sections + + +namespace ParaMEDMEM +{ +/*! + * Returns the attribute \a _name of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return std::string - array name + */ +std::string DataArray::getName() const {} + +/*! + * Returns number of components of \a this array. + * See \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return int - number of components + */ +int DataArray::getNumberOfComponents() const {} + +/*! + * Returns number of tuples of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return int - number of tuples + */ +int DataArray::getNumberOfTuples() const {} + +/*! + * Returns number of elements of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return int - number of elements == this->getNumberOfTuples() * + * this->getNumberOfComponents() + */ +int DataArray::getNbOfElems() const {} + +/*! + * Throws an exception if number of elements in \a this array differs from a given one. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \param [in] nbOfElems - expected array size. + * \param [in] msg - message to return within the thrown exception. + * \throw if this->getNbOfElems() != nbOfElems. + */ +void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const {} + +/*! + * Returns values of a specified tuple. + * \param [in] tupleId - index of the tuple of interest. + * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res + * must be allocated by the caller and be of size not less than \a + * this->getNumberOfComponents(). + */ +void DataArrayDouble::getTuple(int tupleId, double *res) const {} + +/*! + * Returns a value of a specified element of \a this array. + * \param [in] tupleId - index of the tuple of interest. + * \param [in] compoId - index of the component of interest. + * \return double - the value of \a compoId-th component of \a tupleId-th tuple. + */ +double DataArrayDouble::getIJ(int tupleId, int compoId) const {} + +/*! + * Returns a pointer to the first element of the raw data of \a this array. + * \return double* - the pointer to the value of 0-th tuple and 0-th component. + */ +double * DataArrayDouble::getPointer() {} + +/*! + * Returns a const pointer to the first element of the raw data of \a this array. + * \return const double* - the pointer to the value of 0-th tuple and 0-th component. + */ +const double * DataArrayDouble::getConstPointer() const {} + +/*! + * Assigns a given value to a specified element of \a this array. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayDouble::setIJ(int tupleId, int compoId, double newVal) {} + +/*! + * Assigns a given value to a specified element of \a this array which is not marked + * as changed. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal) {} + +/*! + * Copies values from another array starting from a specified element of \a this. + * \param [in] id - index of element to assign the value \a element0 to. + * \param [in] element0 - value to assign to the \a id-th element of \a this. + * \param [in] others - values to assign to elements following the \a id-th + * element of \a this. + * \param [in] sizeOfOthers - number of values to copy from \a others. + */ +void DataArrayDouble::writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) {} + +/*! + * Does nothing because this class does not aggregate any TimeLabel instance. + */ +void DataArrayDouble::updateTime() const {} + +/*! + * Returns values of a specified tuple. + * \param [in] tupleId - index of the tuple of interest. + * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res + * must be allocated by the caller and be of size not less than \a + * this->getNumberOfComponents(). + * + * \ref py_mcdataarrayint_getTuple "Here is a Python example". + */ +void DataArrayInt::getTuple(int tupleId, int *res) const {} + +/*! + * Returns a value of a specified element of \a this array. + * \param [in] tupleId - index of the tuple of interest. + * \param [in] compoId - index of the component of interest. + * \return int - the value of \a compoId-th component of \a tupleId-th tuple. + */ +int DataArrayInt::getIJ(int tupleId, int compoId) const {} + + +/*! + * Assigns a given value to a specified element of \a this array. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + * \warning As this method declares \a this array as modified, it is more optimal to use + * setIJSilent() for modification of muliple values of array and to call + * declareAsNew() after the modification is done. + */ +void DataArrayInt::setIJ(int tupleId, int compoId, int newVal) {} + + +/*! + * Assigns a given value to a specified element of \a this array which is \b not marked + * as changed. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal) {} + +/*! + * Returns a pointer to the first element of the raw data of \a this array. + * \return int* - the pointer to the value of 0-th tuple and 0-th component. + */ +int * DataArrayInt::getPointer() {} + +/*! + * Returns a const pointer to the first element of the raw data of \a this array. + * \return const int* - the pointer to the value of 0-th tuple and 0-th component. + */ +const int * DataArrayInt::getConstPointer() const {} + +/*! + * Copies values from another array starting from a given element of \a this. + * \param [in] id - index of element to assign the value \a element0 to. + * \param [in] element0 - value to assign to the \a id-th element of \a this. + * \param [in] others - values to assign to elements following the \a id-th + * element of \a this. + * \param [in] sizeOfOthers - number of values to copy from \a others. + */ +void DataArrayInt::writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) {} + +} + +namespace ParaMEDMEM +{ +//================================================================================ +/////////////////////// DataArray GROUPPING ////////////////////////////////////// +//================================================================================ + +/*! \name Basic API */ +///@{ +DataArray::setName(const char *name); +DataArray::copyStringInfoFrom(const DataArray& other); +DataArray::areInfoEquals(const DataArray& other) const; +DataArray::getName() const; +DataArray::setInfoOnComponents(const std::vector& info); +DataArray::getVarOnComponent(int i) const; +DataArray::getUnitOnComponent(int i) const; +DataArray::setInfoOnComponent(int i, const char *info); +DataArray::getNumberOfComponents() const; +DataArray::getNumberOfTuples() const; +DataArray::getNbOfElems() const; +DataArray::checkNbOfElems(int nbOfElems, const char *msg) const; +DataArray::GetVarNameFromInfo(const std::string& info); +DataArray::GetUnitFromInfo(const std::string& info); +///@} + +/*! \name Others... */ +///@{ +DataArray::getHeapMemorySize() const; +DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds); +DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other); +DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; +DataArray::reprWithoutNameStream(std::ostream& stream) const; +DataArray::cppRepr(const char *varName) const; +DataArray::getInfoOnComponents() const; +DataArray::getInfoOnComponents(); +DataArray::getVarsOnComponent() const; +DataArray::getUnitsOnComponent() const; +DataArray::getInfoOnComponent(int i) const; +DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const; +DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const; +DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception); +DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); +DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg); +DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg); +DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); +DataArray::reprCppStream(const char *varName, std::ostream& stream) const; +DataArray::DataArray(); +DataArray::CheckValueInRange(int ref, int value, const char *msg); +DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg); +DataArray::CheckClosingParInRange(int ref, int value, const char *msg); +std::string DataArray::_name; +std::vector DataArray::_info_on_compo; +///@} + +//================================================================================ +/////////////////////// DataArrayDouble GROUPPING //////////////////////////////// +//================================================================================ + +/*! \name Basic API */ +///@{ +DataArrayDouble::isAllocated() const; +DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& info); +DataArrayDouble::doubleValue() const; +DataArrayDouble::empty() const; +DataArrayDouble::deepCpy() const; +DataArrayDouble::performCpy(bool deepCpy) const; +DataArrayDouble::cpyFrom(const DataArrayDouble& other); +DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo); +DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo); +DataArrayDouble::fillWithZero(); +DataArrayDouble::fillWithValue(double val); +DataArrayDouble::iota(double init=0.); +DataArrayDouble::isUniform(double val, double eps) const; +DataArrayDouble::sort(bool asc=true); +DataArrayDouble::reverse(); +DataArrayDouble::checkMonotonic(bool increasing, double eps) const; +DataArrayDouble::isMonotonic(bool increasing, double eps) const; +DataArrayDouble::repr() const; +DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const; +DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; +DataArrayDouble::reAlloc(int nbOfTuples); +DataArrayDouble::convertToIntArr() const; +DataArrayDouble::fromNoInterlace() const; +DataArrayDouble::toNoInterlace() const; +DataArrayDouble::renumberInPlace(const int* old2New); +DataArrayDouble::renumberInPlaceR(const int* new2Old); +DataArrayDouble::renumber(const int* old2New) const; +DataArrayDouble::renumberR(const int* new2Old) const; +DataArrayDouble::renumberAndReduce(const int* old2New, int newNbOfTuple) const; +DataArrayDouble::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayDouble::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const; +DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const; +DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd=-1) const; +DataArrayDouble::rearrange(int newNbOfCompo); +DataArrayDouble::transpose(); +DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const; +DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const; +DataArrayDouble::meldWith(const DataArrayDouble* other); +DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; +DataArrayDouble::getDifferentValues(double prec, int limitTupleId=-1) const; +DataArrayDouble::setSelectedComponents(const DataArrayDouble* a, const std::vector& compoIds); +DataArrayDouble::setPartOfValues1(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); +DataArrayDouble::setPartOfValues2(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple2(double a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); +DataArrayDouble::setPartOfValues3(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple3(double a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); +DataArrayDouble::getTuple(int tupleId, double* res) const; +DataArrayDouble::getIJ(int tupleId, int compoId) const; +DataArrayDouble::back() const; +DataArrayDouble::getIJSafe(int tupleId, int compoId) const; +DataArrayDouble::setIJ(int tupleId, int compoId, double newVal); +DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal); +DataArrayDouble::writeOnPlace(int id, double element0, const double* others, int sizeOfOthers); +DataArrayDouble::checkNoNullValues() const; +DataArrayDouble::getMinMaxPerComponent(double* bounds) const; +DataArrayDouble::getMaxValue(int& tupleId) const; +DataArrayDouble::getMaxValueInArray() const; +DataArrayDouble::getMinValue(int& tupleId) const; +DataArrayDouble::getMinValueInArray() const; +DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const; +DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const; +DataArrayDouble::getAverageValue() const; +DataArrayDouble::norm2() const; +DataArrayDouble::normMax() const; +DataArrayDouble::accumulate(double* res) const; +DataArrayDouble::accumulate(int compId) const; +DataArrayDouble::fromPolarToCart() const; +DataArrayDouble::fromCylToCart() const; +DataArrayDouble::fromSpherToCart() const; +DataArrayDouble::doublyContractedProduct() const; +DataArrayDouble::determinant() const; +DataArrayDouble::eigenValues() const; +DataArrayDouble::eigenVectors() const; +DataArrayDouble::inverse() const; +DataArrayDouble::trace() const; +DataArrayDouble::deviator() const; +DataArrayDouble::magnitude() const; +DataArrayDouble::maxPerTuple() const; +DataArrayDouble::sortPerTuple(bool asc); +DataArrayDouble::abs(); +DataArrayDouble::applyLin(double a, double b, int compoId); +DataArrayDouble::applyLin(double a, double b); +DataArrayDouble::applyInv(double numerator); +DataArrayDouble::negate() const; +DataArrayDouble::applyFunc(int nbOfComp, const char* func) const; +DataArrayDouble::applyFunc(const char* func) const; +DataArrayDouble::applyFunc2(int nbOfComp, const char* func) const; +DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char* func) const; +DataArrayDouble::getIdsInRange(double vmin, double vmax) const; +DataArrayDouble::addEqual(const DataArrayDouble* other); +DataArrayDouble::substractEqual(const DataArrayDouble* other); +DataArrayDouble::multiplyEqual(const DataArrayDouble* other); +DataArrayDouble::divideEqual(const DataArrayDouble* other); +DataArrayDouble::updateTime() const; +DataArrayDouble::New(); +DataArrayDouble::Aggregate(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Aggregate(const std::vector& arr); +DataArrayDouble::Meld(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Meld(const std::vector& arr); +DataArrayDouble::Dot(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::CrossProduct(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Max(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Min(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Add(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Substract(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Multiply(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Divide(const DataArrayDouble* a1, const DataArrayDouble* a2); +///@} + +/*! \name Advanced API */ +///@{ +DataArrayDouble::checkAllocated() const; +DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble* a, const DataArrayInt* tuplesSelec); +DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble* a, const DataArrayInt* tuplesSelec); +DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble* a, int bg, int end2, int step); +DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const; +///@} + +/*! \name Others... */ +///@{ +DataArrayDouble::getNumberOfTuples() const; +DataArrayDouble::getNbOfElems() const; +DataArrayDouble::getHeapMemorySize() const; +DataArrayDouble::reserve(int nbOfElems); +DataArrayDouble::pushBackSilent(double val); +DataArrayDouble::popBackSilent(); +DataArrayDouble::pack() const; +DataArrayDouble::getNbOfElemAllocated() const; +DataArrayDouble::reprZip() const; +DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char* nameInFile) const; +DataArrayDouble::reprStream(std::ostream& stream) const; +DataArrayDouble::reprZipStream(std::ostream& stream) const; +DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const; +DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const; +DataArrayDouble::reprCppStream(const char* varName, std::ostream& stream) const; +DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; +DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const; +DataArrayDouble::setPartOfValues4(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); +DataArrayDouble::getPointer(); +DataArrayDouble::SetArrayIn(DataArrayDouble* newArray, DataArrayDouble* &arrayToSet); +DataArrayDouble::iterator(); +DataArrayDouble::getConstPointer() const; +DataArrayDouble::begin() const; +DataArrayDouble::end() const; +DataArrayDouble::useArray(const double* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); +DataArrayDouble::useExternalArrayWithRWAccess(const double* array, int nbOfTuple, int nbOfCompo); +DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last); +DataArrayDouble::computeBBoxPerTuple(double epsilon=0.0) const; +DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble* other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; +DataArrayDouble::recenterForMaxPrecision(double eps); +DataArrayDouble::distanceToTuple(const double* tupleBg, const double* tupleEnd, int& tupleId) const; +DataArrayDouble::buildEuclidianDistanceDenseMatrix() const; +DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble* other) const; +DataArrayDouble::applyFuncFast32(const char* func); +DataArrayDouble::applyFuncFast64(const char* func); +DataArrayDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const; +DataArrayDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const; +DataArrayDouble::resizeForUnserialization(const std::vector& tinyInfoI); +DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); + +DataArrayDouble::findCommonTuplesAlg(const double* bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt* c, DataArrayInt* cI) const; + +DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double* pos, int nbOfTuples, double eps, DataArrayInt* c, DataArrayInt* cI); +DataArrayDouble::DataArrayDouble(); +MemArray DataArrayDouble::_mem; +///@} + +//================================================================================ +/////////////////////// DataArrayInt GROUPPING /////////////////////////////////// +//================================================================================ + +/*! \name Advanced API */ +///@{ +DataArrayInt::checkAllocated() const; +DataArrayInt::getHashCode() const; +DataArrayInt::buildPermutationArr(const DataArrayInt& other) const; +DataArrayInt::transformWithIndArr(const int* indArrBg, const int* indArrEnd); +DataArrayInt::transformWithIndArrR(const int* indArrBg, const int* indArrEnd) const; +DataArrayInt::splitByValueRange(const int* arrBg, const int* arrEnd,DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; +DataArrayInt::setPartOfValuesAdv(const DataArrayInt* a, const DataArrayInt* tuplesSelec); +DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt* tuplesSelec); +DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt* a, int bg, int end2, int step); +DataArrayInt::SetArrayIn(DataArrayInt* newArray, DataArrayInt* &arrayToSet); +///@} + +/*! \name Basic API */ +///@{ +DataArrayInt::isAllocated() const; +DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& info); +DataArrayInt::intValue() const; +DataArrayInt::empty() const; +DataArrayInt::deepCpy() const; +DataArrayInt::performCpy(bool deepCpy) const; +DataArrayInt::cpyFrom(const DataArrayInt& other); +DataArrayInt::alloc(int nbOfTuple, int nbOfCompo); +DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo); +DataArrayInt::isEqual(const DataArrayInt& other) const; +DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const; +DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; +DataArrayInt::sort(bool asc=true); +DataArrayInt::reverse(); +DataArrayInt::fillWithZero(); +DataArrayInt::fillWithValue(int val); +DataArrayInt::iota(int init=0); +DataArrayInt::repr() const; +DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const; +DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const; +DataArrayInt::reAlloc(int nbOfTuples); +DataArrayInt::convertToDblArr() const; +DataArrayInt::fromNoInterlace() const; +DataArrayInt::toNoInterlace() const; +DataArrayInt::renumberInPlace(const int* old2New); +DataArrayInt::renumberInPlaceR(const int* new2Old); +DataArrayInt::renumber(const int* old2New) const; +DataArrayInt::renumberR(const int* new2Old) const; +DataArrayInt::renumberAndReduce(const int* old2NewBg, int newNbOfTuple) const; +DataArrayInt::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayInt::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayInt::selectByTupleId2(int bg, int end, int step) const; +DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const; +DataArrayInt::checkAndPreparePermutation() const; +DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; +DataArrayInt::buildPermArrPerLevel() const; +DataArrayInt::isIdentity() const; +DataArrayInt::isUniform(int val) const; +DataArrayInt::substr(int tupleIdBg, int tupleIdEnd=-1) const; +DataArrayInt::rearrange(int newNbOfCompo); +DataArrayInt::transpose(); +DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const; +DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const; +DataArrayInt::meldWith(const DataArrayInt* other); +DataArrayInt::setSelectedComponents(const DataArrayInt* a, const std::vector& compoIds); +DataArrayInt::setPartOfValues1(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); +DataArrayInt::setPartOfValues2(const DataArrayInt* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple2(int a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); +DataArrayInt::setPartOfValues3(const DataArrayInt* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple3(int a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); +DataArrayInt::getTuple(int tupleId, int* res) const; +DataArrayInt::getIJ(int tupleId, int compoId) const; +DataArrayInt::getIJSafe(int tupleId, int compoId) const; +DataArrayInt::back() const; +DataArrayInt::setIJ(int tupleId, int compoId, int newVal); +DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal); +DataArrayInt::getPointer(); +DataArrayInt::getConstPointer() const; +DataArrayInt::getIdsEqual(int val) const; +DataArrayInt::getIdsNotEqual(int val) const; +DataArrayInt::getIdsEqualList(const int* valsBg, const int* valsEnd) const; +DataArrayInt::getIdsNotEqualList(const int* valsBg, const int* valsEnd) const; +DataArrayInt::changeValue(int oldValue, int newValue); +DataArrayInt::presenceOfValue(int value) const; +DataArrayInt::presenceOfValue(const std::vector& vals) const; +DataArrayInt::getMaxValue(int& tupleId) const; +DataArrayInt::getMaxValueInArray() const; +DataArrayInt::getMinValue(int& tupleId) const; +DataArrayInt::getMinValueInArray() const; +DataArrayInt::abs(); +DataArrayInt::applyLin(int a, int b, int compoId); +DataArrayInt::applyLin(int a, int b); +DataArrayInt::applyInv(int numerator); +DataArrayInt::negate() const; +DataArrayInt::applyDivideBy(int val); +DataArrayInt::applyModulus(int val); +DataArrayInt::applyRModulus(int val); +DataArrayInt::buildComplement(int nbOfElement) const; +DataArrayInt::buildSubstraction(const DataArrayInt* other) const; +DataArrayInt::buildUnion(const DataArrayInt* other) const; +DataArrayInt::buildIntersection(const DataArrayInt* other) const; +DataArrayInt::deltaShiftIndex() const; +DataArrayInt::computeOffsets(); +DataArrayInt::computeOffsets2(); +DataArrayInt::buildExplicitArrByRanges(const DataArrayInt* offsets) const; +DataArrayInt::useArray(const int* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); +DataArrayInt::writeOnPlace(int id, int element0, const int* others, int sizeOfOthers); +DataArrayInt::addEqual(const DataArrayInt* other); +DataArrayInt::substractEqual(const DataArrayInt* other); +DataArrayInt::multiplyEqual(const DataArrayInt* other); +DataArrayInt::divideEqual(const DataArrayInt* other); +DataArrayInt::modulusEqual(const DataArrayInt* other); +DataArrayInt::updateTime() const; +DataArrayInt::New(); +DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int* arr, const int* arrIBg, const int* arrIEnd, int &newNbOfTuples); +DataArrayInt::Aggregate(const DataArrayInt* a1, const DataArrayInt* a2, int offsetA2); +DataArrayInt::Aggregate(const std::vector& arr); +DataArrayInt::Meld(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Meld(const std::vector& arr); +DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); +DataArrayInt::BuildUnion(const std::vector& arr); +DataArrayInt::BuildIntersection(const std::vector& arr); +DataArrayInt::Add(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Substract(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Multiply(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Divide(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Modulus(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::CheckAndPreparePermutation(const int* start, const int* end); +DataArrayInt::Range(int begin, int end, int step); +///@} + +/*! \name Others... */ +///@{ +DataArrayInt::getNumberOfTuples() const; +DataArrayInt::getNbOfElems() const; +DataArrayInt::getHeapMemorySize() const; +DataArrayInt::reserve(int nbOfElems); +DataArrayInt::pushBackSilent(int val); +DataArrayInt::popBackSilent(); +DataArrayInt::pack() const; +DataArrayInt::getNbOfElemAllocated() const; +DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; +DataArrayInt::checkMonotonic(bool increasing) const; +DataArrayInt::isMonotonic(bool increasing) const; +DataArrayInt::checkStrictlyMonotonic(bool increasing) const; +DataArrayInt::isStrictlyMonotonic(bool increasing) const; +DataArrayInt::reprZip() const; +DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char* type, const char* nameInFile) const; +DataArrayInt::reprStream(std::ostream& stream) const; +DataArrayInt::reprZipStream(std::ostream& stream) const; +DataArrayInt::reprWithoutNameStream(std::ostream& stream) const; +DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const; +DataArrayInt::reprCppStream(const char* varName, std::ostream& stream) const; +DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const; +DataArrayInt::setPartOfValues4(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); +DataArrayInt::iterator(); +DataArrayInt::begin() const; +DataArrayInt::end() const; +DataArrayInt::locateTuple(const std::vector& tupl) const; +DataArrayInt::locateValue(int value) const; +DataArrayInt::locateValue(const std::vector& vals) const; +DataArrayInt::search(const std::vector& vals) const; +DataArrayInt::presenceOfTuple(const std::vector& tupl) const; +DataArrayInt::accumulate(int* res) const; +DataArrayInt::accumulate(int compId) const; +DataArrayInt::getIdsInRange(int vmin, int vmax) const; +DataArrayInt::buildSubstractionOptimized(const DataArrayInt* other) const; +DataArrayInt::buildUnique() const; +DataArrayInt::findRangeIdForEachTuple(const DataArrayInt* ranges) const; +DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt* ranges) const; +DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const; +DataArrayInt::getDifferentValues() const; +> DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const; +DataArrayInt::useExternalArrayWithRWAccess(const int* array, int nbOfTuple, int nbOfCompo); +tor> +DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last); +DataArrayInt::getTinySerializationIntInformation(std::vector& tinyInfo) const; +DataArrayInt::getTinySerializationStrInformation(std::vector& tinyInfo) const; +DataArrayInt::resizeForUnserialization(const std::vector& tinyInfoI); +DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); +DataArrayInt::DataArrayInt(); +MemArray DataArrayInt::_mem; +///@} + +} diff --git a/doc/doxygen/fakesources/MEDCouplingMesh.C b/doc/doxygen/fakesources/MEDCouplingMesh.C new file mode 100644 index 000000000..ac6f20661 --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingMesh.C @@ -0,0 +1,178 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods of DataArray* classes +// * groupping methods into "Basic API", "Advanced" and "Others..." sections + + +namespace ParaMEDMEM +{ + //================================================================================ + /*! + * Checks if \a this and another MEDCouplingMesh are equal without considering + * textual data like mesh name, names of spatial components etc. + * \param [in] other - an instance of MEDCouplingMesh to compare with \a this one. + * \param [in] prec - precision value used to compare node coordinates. + * \return bool - \c true if the two meshes are equal, \c false else. + */ + //================================================================================ + + bool MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const {} + + /*! + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are + * considered equivalent if (1) \a this mesh contains the same nodes as the \a other + * mesh (with a specified precision) and (2) \a this mesh contains the same cells as + * the \a other mesh (with use of a specified cell comparison technique). The mapping + * from \a other to \a this for nodes and cells is returned via out parameters. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of + * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). + * \param [in] prec - the precision used to compare nodes of the two meshes. + * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + */ + void MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) {} + + /*! + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are considered equivalent if (1) they share the same + * node coordinates array(s) and (2) they contain the same cells (with use of a specified + * cell comparison technique). The mapping from cells of the \a other to ones of \a this + * is returned via an out parameter. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of + * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). + * \param [in] prec - a not used parameter. + * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + */ + void MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) {} +} + +namespace ParaMEDMEM +{ +//================================================================================ +/////////////////////// GROUPPING members of MEDCouplingMesh ///////////////////// +//================================================================================ +/*! \name Basic API */ +///@{ + MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); + MEDCouplingMesh::MergeMeshes(std::vector& meshes); + MEDCouplingMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const; + MEDCouplingMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const; + MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const; + MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const; + MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const char *func) const; + MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; + MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; + MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const; + MEDCouplingMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; + MEDCouplingMesh::writeVTK(const char *fileName) const; +///@} + +/*! \name Advanced API */ +///@{ + MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; +///@} + +/*! \name Others... */ +///@{ + MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCouplingMesh::MEDCouplingMesh(); + MEDCouplingMesh::~MEDCouplingMesh(); + MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other); + MEDCouplingMesh::advancedRepr() const = 0; + MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const; + MEDCouplingMesh::buildOrthogonalField() const = 0; + MEDCouplingMesh::buildPart(const int *start, const int *end) const = 0; + MEDCouplingMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + MEDCouplingMesh::buildUnstructured() const; + MEDCouplingMesh::checkCoherency() const; + MEDCouplingMesh::checkCoherency1(double eps=1e-12) const; + MEDCouplingMesh::checkCoherency2(double eps=1e-12) const; + MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCouplingMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; + MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell() const; + MEDCouplingMesh::computeNbOfNodesPerCell() const; + MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other); + MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCouplingMesh::deepCpy() const = 0; + MEDCouplingMesh::getAllGeoTypes() const = 0; + MEDCouplingMesh::getBarycenterAndOwner() const = 0; + MEDCouplingMesh::getBoundingBox(double *bbox) const = 0; + MEDCouplingMesh::getCellContainingPoint(const double *pos, double eps) const = 0; + MEDCouplingMesh::getCoordinatesAndOwner() const = 0; + MEDCouplingMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const; + MEDCouplingMesh::getDescription() const; + MEDCouplingMesh::getDistributionOfTypes() const; + MEDCouplingMesh::getHeapMemorySize() const; + MEDCouplingMesh::getMeasureField(bool isAbs) const = 0; + MEDCouplingMesh::getMeasureFieldOnNode(bool isAbs) const = 0; + MEDCouplingMesh::getMeshDimension() const = 0; + MEDCouplingMesh::getName() const; + MEDCouplingMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const = 0; + MEDCouplingMesh::getNumberOfCells() const = 0; + MEDCouplingMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; + MEDCouplingMesh::getNumberOfNodes() const = 0; + MEDCouplingMesh::getSpaceDimension() const = 0; + MEDCouplingMesh::getTime(int& iteration, int& order) const; + MEDCouplingMesh::getTimeUnit() const; + MEDCouplingMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const = 0; + MEDCouplingMesh::getType() const = 0; + MEDCouplingMesh::getTypeOfCell(int cellId) const = 0; + MEDCouplingMesh::getVTKDataSetType() const; + MEDCouplingMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCouplingMesh::isStructured() const; + MEDCouplingMesh::mergeMyselfWith(const MEDCouplingMesh *other) const = 0; + MEDCouplingMesh::renumberCells(const int *old2NewBg, bool check=true); + MEDCouplingMesh::reprQuickOverview(std::ostream& stream) const; + MEDCouplingMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const = 0; + MEDCouplingMesh::rotate(const double *center, const double *vector, double angle) = 0; + MEDCouplingMesh::scale(const double *point, double factor) = 0; + MEDCouplingMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; + MEDCouplingMesh::setDescription(const char *descr); + MEDCouplingMesh::setName(const char *name); + MEDCouplingMesh::setTime(double val, int iteration, int order); + MEDCouplingMesh::setTimeUnit(const char *unit); + MEDCouplingMesh::simpleRepr() const = 0; + MEDCouplingMesh::simplexize(int policy); + MEDCouplingMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; + MEDCouplingMesh::translate(const double *vector) = 0; + MEDCouplingMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,const std::vector& littleStrings) = 0; + MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const; + MEDCouplingMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const; + MEDCouplingMesh::_description; + MEDCouplingMesh::_iteration; + MEDCouplingMesh::_name; + MEDCouplingMesh::_order; + MEDCouplingMesh::_time; + MEDCouplingMesh::_time_unit; +///@} +} diff --git a/doc/doxygen/fakesources/MEDCouplingPointSet.C b/doc/doxygen/fakesources/MEDCouplingPointSet.C new file mode 100644 index 000000000..5e449c9fb --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingPointSet.C @@ -0,0 +1,55 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods of MEDCouplingPointSet + +namespace ParaMEDMEM +{ + + /*! + * Tries to use a coordinates array of \a other mesh for \a this one. If all nodes + * of \a this mesh coincide, within a specified precision, with some nodes of \a + * other mesh, then \a this mesh refers to the coordinates array of the \a other mesh, + * i.e. \a this->_coords = \a other._coords. Otherwise an exception is thrown and \a + * this remains unchanged. + * \param [in] other - the other mesh. + * \param [in] epsilon - the precision to compare node coordinates of the two meshes. + * \throw If the coordinates array of \a this is not set. + * \throw If the coordinates array of \a other is not set. + * \throw If not all nodes of \a this mesh are present in the \a other mesh. + */ + void MEDCouplingPointSet::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) {} + + /*! + * Returns a const pointer to the node coordinates array of \a this mesh \b without + * incrementing its reference counter, thus there is no need to decrRef() it by the caller. + */ + const DataArrayDouble *MEDCouplingPointSet::getCoords() const { return _coords; } + + /*! + * Returns a pointer to the node coordinates array of \a this mesh \b without + * incrementing its reference counter, thus there is no need to decrRef() it by the caller. + */ + DataArrayDouble *MEDCouplingPointSet::getCoords() { return _coords; } + + + //! size of returned tinyInfo must be always the same. + void MEDCouplingPointSet::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const {} +} diff --git a/doc/doxygen/fakesources/MEDCouplingUMesh.C b/doc/doxygen/fakesources/MEDCouplingUMesh.C new file mode 100644 index 000000000..84c23f181 --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingUMesh.C @@ -0,0 +1,343 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods of MEDCouplingUMesh class, +// * groupping methods into "Basic API", "Advanced" and "Others..." sections + +namespace ParaMEDMEM +{ + /*! + * Returns the nodal connectivity array. For more info on how data in stored in + * this array, see \ref MEDCouplingUMeshAdvBuild. + * \return const DataArrayInt * - a pointer to the nodal connectivity array + * referred by \a this mesh. + */ + const DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() const {} + /*! + * Returns the nodal connectivity index array. For more info on how data in stored in + * this array, see \ref MEDCouplingUMeshAdvBuild. + * \return const DataArrayInt * - a pointer to the nodal connectivity index array + * referred by \a this mesh. + */ + const DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() const {} + /*! + * Returns the nodal connectivity array. For more info on how data in stored in + * this array, see \ref MEDCouplingUMeshAdvBuild. + * \return const DataArrayInt * - a pointer to the nodal connectivity array + * referred by \a this mesh. + */ + DataArrayInt * MEDCouplingUMesh::getNodalConnectivity() {} + /*! + * Returns the nodal connectivity index array. For more info on how data in stored in + * this array, see \ref MEDCouplingUMeshAdvBuild. + * \return const DataArrayInt * - a pointer to the nodal connectivity index array + * referred by \a this mesh. + */ + DataArrayInt * MEDCouplingUMesh::getNodalConnectivityIndex() {} +} + +namespace ParaMEDMEM +{ +//================================================================================ +/////////////////////// MEDCouplingUMesh GROUPPING /////////////////////////////// +//================================================================================ + +/*! \name Basic API */ +///@{ +MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); +MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2); +MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps); +MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); +MEDCouplingUMesh::MergeUMeshes(std::vector& a); +MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); +MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector& meshes); +MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector& meshes); +MEDCouplingUMesh::allocateCells(int nbOfCells); +MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const; +MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; +MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const; +MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const; +MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; +MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; +MEDCouplingUMesh::buildDirectionVectorField() const; +MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; +MEDCouplingUMesh::buildOrthogonalField() const; +MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; +MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; +MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const; +MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; +MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; +MEDCouplingUMesh::checkCoherency() const; +MEDCouplingUMesh::checkCoherency1(double eps=1e-12) const; +MEDCouplingUMesh::checkCoherency2(double eps=1e-12) const; +MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor) const; +MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; +MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; +MEDCouplingUMesh::clone(bool recDeepCpy) const; +MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const; +MEDCouplingUMesh::convertAllToPoly(); +MEDCouplingUMesh::convertQuadraticCellsToLinear(); +MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); +MEDCouplingUMesh::deepCpy() const; +MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells(); +MEDCouplingUMesh::findBoundaryNodes() const; +MEDCouplingUMesh::finishInsertingCells(); +MEDCouplingUMesh::getAllGeoTypes() const; +MEDCouplingUMesh::getAspectRatioField() const; +MEDCouplingUMesh::getBarycenterAndOwner() const; +MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const; +MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const; +MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; +MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; +MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; +MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; +MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); +MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const; +MEDCouplingUMesh::getEdgeRatioField() const; +MEDCouplingUMesh::getMeasureField(bool isAbs) const; +MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const; +MEDCouplingUMesh::getMeshDimension() const; +MEDCouplingUMesh::getNodalConnectivity() const; +MEDCouplingUMesh::getNodalConnectivity(); +MEDCouplingUMesh::getNodalConnectivityIndex() const; +MEDCouplingUMesh::getNodalConnectivityIndex(); +MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const; +MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const; +MEDCouplingUMesh::getNumberOfCells() const; +MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const; +MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const; +MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; +MEDCouplingUMesh::getSkewField() const; +MEDCouplingUMesh::getTypeOfCell(int cellId) const; +MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const; +MEDCouplingUMesh::getWarpField() const; +MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); +MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; +MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); +MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); +MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly); +MEDCouplingUMesh::orientCorrectlyPolyhedrons(); +MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes); +MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); +MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N); +MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const; +MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); +MEDCouplingUMesh::setMeshDimension(int meshDim); +MEDCouplingUMesh::sortCellsInMEDFileFrmt(); +MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon); +MEDCouplingUMesh::unPolyze(); +MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId=0); +MEDCouplingUMesh::zipCoordsTraducer(); + ///@} + + /*! \name Advanced API */ +///@{ +MEDCouplingUMesh::areOnlySimplexCells() const; +MEDCouplingUMesh::checkButterflyCells(std::vector& cells, double eps=1e-12) const; +MEDCouplingUMesh::computeTypes(); +MEDCouplingUMesh::convertDegeneratedCells(); +MEDCouplingUMesh::convertExtrudedPolyhedra(); +MEDCouplingUMesh::getMeshLength() const; +MEDCouplingUMesh::isFullyQuadratic() const; +MEDCouplingUMesh::isPresenceOfQuadratic() const; +MEDCouplingUMesh::simplexize(int policy); +MEDCouplingUMesh::tessellate2D(double eps); +MEDCouplingUMesh::tessellate2DCurve(double eps); + ///@ + +/*! \name Others... */ +///@{ +MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms,DataArrayInt *&szOfCellGrpOfSameType,DataArrayInt *&idInMsOfCellGrpOfSameType); +MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); +MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); +MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); +MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); +MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); +MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); +MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); +MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; +MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,const int *nodal3DCurve, const int *nodalIndx3DCurve,const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf); +MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da); +MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut); +MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector& addCoo, const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge); +MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector >& intesctEdges1, const std::vector< std::vector >& colinear2,const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector >& intesctEdges2,const std::vector& addCoords,std::vector& addCoordsQuadratic, std::vector& cr, std::vector& crI, std::vector& cNb1, std::vector& cNb2); +MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI,DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); +MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector& code); +MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn); +MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); +MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); +MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p); +MEDCouplingUMesh::CorrectExtrudedCell(int *begin, int *end); +MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end); +MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); +MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); +MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI,DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr); +MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2,MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,std::vector& addCoo); +MEDCouplingUMesh::Is3DExtrudedCellWellOriented(const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords); +MEDCouplingUMesh::MEDCouplingUMesh(); +MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); +MEDCouplingUMesh::MergeUMeshesLL(std::vector& a); +MEDCouplingUMesh::New(); +MEDCouplingUMesh::New(const char *meshName, int meshDim); +MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0); +MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); +MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); +MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); +MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); +MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res); +MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords); +MEDCouplingUMesh::advancedRepr() const; +MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const; +MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; +MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf,const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const; +MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); +MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; +MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; +MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; +MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const; +MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const; +MEDCouplingUMesh::buildSpreadZonesWithPoly() const; +MEDCouplingUMesh::buildUnionOf2DMesh() const; +MEDCouplingUMesh::buildUnionOf3DMesh() const; +MEDCouplingUMesh::buildUnstructured() const; +MEDCouplingUMesh::cellIterator(); +MEDCouplingUMesh::cellsByType(); +MEDCouplingUMesh::checkConnectivityFullyDefined() const; +MEDCouplingUMesh::checkConsecutiveCellTypes() const; +MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; +MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const; +MEDCouplingUMesh::checkFullyDefined() const; +MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; +MEDCouplingUMesh::computeFetchedNodeIds() const; +MEDCouplingUMesh::computeNbOfNodesPerCell() const; +MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; +MEDCouplingUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const; +MEDCouplingUMesh::computeSkin() const; +MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType=0); +MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; +MEDCouplingUMesh::convexEnvelop2D(); +MEDCouplingUMesh::cppRepr() const; +MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId, int& nodeId) const; +MEDCouplingUMesh::distanceToPoint2DCurveAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const; +MEDCouplingUMesh::distanceToPoint3DSurfAlg(const double *pt, const DataArrayInt *cellIds, double& ret0, int& cellId) const; +MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); +MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset); +MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const; +MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; +MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; +MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; +MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; +MEDCouplingUMesh::findAndCorrectBadOriented3DCells(); +MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const; +MEDCouplingUMesh::findCellIdsOnBoundary() const; +MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; +MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const; +MEDCouplingUMesh::getAllTypes() const; +MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector& bbox) const; +MEDCouplingUMesh::getDistributionOfTypes() const; +MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const; +MEDCouplingUMesh::getHeapMemorySize() const; +MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const; +MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; +MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const; +MEDCouplingUMesh::getQuadraticStatus() const; +MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; +MEDCouplingUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; +MEDCouplingUMesh::getType() const { return UNSTRUCTURED; } +MEDCouplingUMesh::getVTKDataSetType() const; +MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; +MEDCouplingUMesh::isContiguous1D() const; +MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const; +MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; +MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const; +MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; +MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const; +MEDCouplingUMesh::partitionBySpreadZone() const; +MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const; +MEDCouplingUMesh::rearrange2ConsecutiveCellTypes(); +MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check=true); +MEDCouplingUMesh::reprConnectivityOfThis() const; +MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const; +MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; +MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; +MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis); +MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis); +MEDCouplingUMesh::shiftNodeNumbersInConn(int delta); +MEDCouplingUMesh::simpleRepr() const; +MEDCouplingUMesh::simplexizePlanarFace5(); +MEDCouplingUMesh::simplexizePlanarFace6(); +MEDCouplingUMesh::simplexizePol0(); +MEDCouplingUMesh::simplexizePol1(); +MEDCouplingUMesh::simplifyPolyhedra(double eps); +MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve); +MEDCouplingUMesh::splitByType() const; +MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; +MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); +MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); +MEDCouplingUMesh::updateTime() const; +MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const; +MEDCouplingUMesh::~MEDCouplingUMesh(); +template MEDCouplingUMesh * MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; +template void MEDCouplingUMesh::getCellsContainingPointsAlg +(const double *coords, const double *pos, int nbOfPoints,double eps, std::vector& elts, + std::vector& eltsIndex) const; + +const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER]; +const int MEDCouplingUMesh::N_MEDMEM_ORDER=24; +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION; +int MEDCouplingUMesh::_mesh_dim; +std::set MEDCouplingUMesh::_types; +DataArrayInt * MEDCouplingUMesh::_nodal_connec; +DataArrayInt * MEDCouplingUMesh::_nodal_connec_index; + ///@} +} + diff --git a/doc/doxygen/fakesources/MEDFileField.C b/doc/doxygen/fakesources/MEDFileField.C new file mode 100644 index 000000000..4b8362a6e --- /dev/null +++ b/doc/doxygen/fakesources/MEDFileField.C @@ -0,0 +1,106 @@ +// MEDFileFieldGlobsReal::Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// generation of documentation for inline methods. + + +namespace ParaMEDMEM // inline methods of MEDFileField1TSWithoutSDA +{ + /*! + * Returns the number of iteration where \a this field has been calculated. + * \return int - the iteration number. + */ + int MEDFileField1TSWithoutSDA::getIteration() const {} + /*! + * Returns the order number of iteration where \a this field has been calculated. + * \return int - the order number. + */ + int MEDFileField1TSWithoutSDA::getOrder() const {} + /*! + * Returns time, number of iteration and order number of iteration when + * \a this field has been calculated. + * \param [out] iteration - the iteration number. + * \param [out] order - the order number. + * \return double - the time value. + */ + double MEDFileField1TSWithoutSDA::getTime(int& iteration, int& order) const {} + /*! + * Sets time, number of iteration and order number of iteration when + * \a this field has been calculated. + * \param [in] val - the time value. + * \param [in] iteration - the iteration number. + * \param [in] order - the order number. + */ + void MEDFileField1TSWithoutSDA::setTime(int iteration, int order, double val) {} + /*! + * Returns units in which the time is measured. + * \return const char * - the time unit name. + */ + const std::string& MEDFileField1TSWithoutSDA::getDtUnit() const {} +} + +namespace ParaMEDMEM // inline methods of MEDFileFieldGlobsReal +{ + /*! + * Returns non empty names of all used profiles. To get all profiles call getPfls(). + * \warning If a profile is used several times, its name is returned **only once**. + * To have a profile name in the result each time it is used, call + * getPflsReallyUsedMulti(). + * \return std::vector - a sequence of names of used profiles. + */ + std::vector MEDFileFieldGlobsReal::getPflsReallyUsed() const {} + /*! + * Returns non empty names of all used localizations. To get all localizations call getLocs(). + * \warning If a localization is used several times, its name is returned **only once**. + * To have a localization name in the result each time it is used, call + * getLocsReallyUsedMulti(). + * \return std::vector - a sequence of names of used localizations. + */ + std::vector MEDFileFieldGlobsReal::getLocsReallyUsed() const {} + /*! + * Returns non empty names of all used profiles as many times as they are used. + * \return std::vector - a sequence of names of used profiles. + */ + std::vector MEDFileFieldGlobsReal::getPflsReallyUsedMulti() const {} + /*! + * Returns non empty names of all used localizations as many times as they are used. + * \return std::vector - a sequence of names of used localizations. + */ + std::vector MEDFileFieldGlobsReal::getLocsReallyUsedMulti() const {} + /*! + * Replaces references to some profiles (a reference is a profile name) by references + * to other profiles. + * \param [in] mapOfModif - a sequence describing required replacements. Each element of + * this sequence is a pair whose + * - the first item is a vector of profile names to replace by the second item, + * - the second item is a profile name to replace every profile of the first item. + */ + void MEDFileFieldGlobsReal::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {} + /*! + * Replaces references to some localizations (a reference is a localization name) by references + * to other localizations. + * \param [in] mapOfModif - a sequence describing required replacements. Each element of + * this sequence is a pair whose + * - the first item is a vector of localization names to replace by the second item, + * - the second item is a localization name to replace every localization of the first + * item. + */ + void MEDFileFieldGlobsReal::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) {} +} diff --git a/doc/doxygen/fakesources/MEDFileMesh.C b/doc/doxygen/fakesources/MEDFileMesh.C new file mode 100644 index 000000000..664e045f2 --- /dev/null +++ b/doc/doxygen/fakesources/MEDFileMesh.C @@ -0,0 +1,353 @@ +// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// + +// This file contains some code used only for +// * generation of documentation for inline methods, +// * groupping methods into "Basic API", "Advanced" and "Others..." sections + + +namespace ParaMEDMEM +{ + /*! + * Sets the name of \a this mesh. + * \param [in] name - the new mesh name. + */ + void MEDFileMesh::setName(const char *name) {} + /*! + * Returns the name of \a this mesh. + * \return const char* name - the mesh name. + */ + const char *MEDFileMesh::getName() const {} + /*! + * Sets the universal name of \a this mesh. The universal name uniquely identifies the mesh. + * \param [in] name - the new universal mesh name. + */ + void MEDFileMesh::setUnivName(const char *name) {} + /*! + * Returns the universal name of \a this mesh. The universal name uniquely identifies the mesh. + * \return const char * - the universal mesh name. + */ + const char *MEDFileMesh::getUnivName() const {} + /*! + * Sets the description of \a this mesh. + * \param [in] name - the new mesh description. + */ + void MEDFileMesh::setDescription(const char *name) {} + /*! + * Returns the description of \a this mesh. + * \return const char* - the mesh description. + */ + const char *MEDFileMesh::getDescription() const {} + /*! + * Sets the order number of iteration of \a this mesh state. + * \param [in] order - the order number. + */ + void MEDFileMesh::setOrder(int order) {} + /*! + * Returns the order number of iteration of \a this mesh state. + * \return int - the order number. + */ + int MEDFileMesh::getOrder() const {} + /*! + * Sets the number of iteration of \a this mesh state. + * \param [in] it - the iteration number. + */ + void MEDFileMesh::setIteration(int it) {} + /*! + * Returns the number of iteration of \a this mesh state. + * \return int - the iteration number. + */ + int MEDFileMesh::getIteration() const {} + /*! + * Sets the time of \a this mesh state. + * \param [in] val - the time value. + */ + void MEDFileMesh::setTimeValue(double time) {} + /*! + * Sets time, the number of iteration and the order number of iteration + * of \a this mesh state. + * \param [in] val - the time value. + * \param [in] iteration - the iteration number. + * \param [in] order - the order number. + */ + void MEDFileMesh::setTime(int dt, int it, double time) {} + /*! + * Returns time, the number of iteration and the order number of iteration + * of \a this mesh state. + * \param [out] iteration - the iteration number. + * \param [out] order - the order number. + * \return double - the time value. + */ + double MEDFileMesh::getTime(int& dt, int& it) {} + /*! + * Returns the time of \a this mesh state. + * \return double - the time value. + */ + double MEDFileMesh::getTimeValue() const {} + /*! + * Sets units in which the time is measured. + * \param [in] unit - the time unit name. + */ + void MEDFileMesh::setTimeUnit(const char *unit) {} + /*! + * Returns units in which the time is measured. + * \return const char * - the time unit name. + */ + const char *MEDFileMesh::getTimeUnit() const {} + /*! + * Returns names and ids of all families in \a this mesh. + * \return const std::map& - a map of a family name to a family id. + */ + const std::map& MEDFileMesh::getFamilyInfo() const {} + /*! + * Returns names of all groups and families constituting them in \a this mesh. + * \return const std::map >& - + * a map of a group name to a vector of names of families constituting the group. + */ + const std::map >& MEDFileMesh::getGroupInfo() const {} + /*! + * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. + * \return std::vector - a sequence of the relative dimensions. + */ + std::vector MEDFileMesh::getNonEmptyLevels() const {} + /*! + * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. + * \return std::vector - a sequence of the relative dimensions. + */ + std::vector MEDFileMesh::getNonEmptyLevelsExt() const {} + /*! + * Returns number of mesh entities of a given relative dimension in \a this mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of interest. + * \return int - the number of entities. + * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh. + */ + int MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a MEDCouplingMesh of a given relative dimension. + * \param [in] meshDimRelToMax - the relative dimension of interest. + * \param [in] renum - if \c true, the returned mesh is permuted according to the + * optional numbers of mesh entities. + * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + * \throw If \a renum == \c true but permutation is impossible. + */ + MEDCouplingMesh *MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the dimension on cells in \a this mesh. + * \return int - the mesh dimension. + * \throw If there are no cells in this mesh. + */ + int MEDFileMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns a full textual description of \a this mesh. + * \return std::string - the string holding the mesh description. + */ + std::string MEDFileMesh::advancedRepr() const {} + /*! + * Sets the family field of a given relative dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which + * the family field is set. + * \param [in] famArr - the array of the family field. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + * \throw If \a famArr has an invalid size. + */ + void MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception) {} + /*! + * Sets the optional numbers of mesh entities of a given dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \param [in] renumArr - the array of the numbers. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + * \throw If \a renumArr has an invalid size. + */ + void MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the family field for mesh entities of a given dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \return const DataArrayInt * - the family field. It is an array of ids of families + * each mesh entity belongs to. It can be NULL. + */ + const DataArrayInt *MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the optional numbers of mesh entities of a given dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \return const DataArrayInt * - the array of the entity numbers. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ + const DataArrayInt *MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns the optional numbers of mesh entities of a given dimension transformed using + * DataArrayInt::invertArrayN2O2O2N(). + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \return const DataArrayInt * - the array of the entity numbers transformed using + * DataArrayInt::invertArrayN2O2O2N(). + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ + const DataArrayInt *MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) {} + /*! + * Returns ids of mesh entities contained in given families of a given dimension. + * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids + * are required. + * \param [in] fams - the names of the families of interest. + * \param [in] renum - if \c true, the optional numbers of entities, if available, are + * returned instead of ids. + * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * numbers, if available and required, of mesh entities of the families. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the family field is missing for \a meshDimRelToMaxExt. + */ + DataArrayInt *MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const throw(INTERP_KERNEL::Exception) {} +} + + +namespace ParaMEDMEM +{ + /*! \name Basic API */ + ///@{ + MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created); +MEDFileMesh::New(const char *fileName); +MEDFileMesh::New(const char *fileName, const char *mName, int dt=-1, int it=-1); +MEDFileMesh::addFamily(const char *familyName, int id); +MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName); +MEDFileMesh::advancedRepr() const = 0; +MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const; +MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const; +MEDFileMesh::assignFamilyNameWithGroupName(); +MEDFileMesh::changeFamilyId(int oldId, int newId); +MEDFileMesh::changeFamilyName(const char *oldName, const char *newName); +MEDFileMesh::changeGroupName(const char *oldName, const char *newName); +MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other); +MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName); +MEDFileMesh::existsFamily(const char *familyName) const; +MEDFileMesh::existsFamily(int famId) const; +MEDFileMesh::existsGroup(const char *groupName) const; +MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created); +MEDFileMesh::getDescription() const; +MEDFileMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; +MEDFileMesh::getFamiliesIds(const std::vector& famNames) const; +MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const; +MEDFileMesh::getFamiliesNames() const; +MEDFileMesh::getFamiliesOnGroup(const char *name) const; +MEDFileMesh::getFamiliesOnGroups(const std::vector& grps) const; +MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum=false) const; +MEDFileMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; +MEDFileMesh::getFamilyId(const char *name) const; +MEDFileMesh::getFamilyInfo() const; +MEDFileMesh::getFamilyNameGivenId(int id) const; +MEDFileMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; +MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum=false) const; +MEDFileMesh::getGroupInfo() const; +MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; +MEDFileMesh::getGroupsNames() const; +MEDFileMesh::getGroupsOnFamily(const char *name) const; +MEDFileMesh::getIteration() const; +MEDFileMesh::getMaxFamilyId() const; +MEDFileMesh::getMeshDimension() const; +MEDFileMesh::getName() const; +MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum=false) const; +MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum=false) const; +MEDFileMesh::getNodeGroupArr(const char *grp, bool renum=false) const; +MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum=false) const; +MEDFileMesh::getNonEmptyLevels() const = 0; +MEDFileMesh::getNonEmptyLevelsExt() const = 0; +MEDFileMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const; +MEDFileMesh::getOrder() const; +MEDFileMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; +MEDFileMesh::getSizeAtLevel(int meshDimRelToMaxExt) const; +MEDFileMesh::getTime(int& dt, int& it); +MEDFileMesh::getTimeUnit() const; +MEDFileMesh::getTimeValue() const; +MEDFileMesh::getUnivName() const; +MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const; +MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& levs); +MEDFileMesh::removeFamily(const char *name); +MEDFileMesh::removeGroup(const char *name); +MEDFileMesh::setDescription(const char *name); +MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector& famIds); +MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector& fams); +MEDFileMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); +MEDFileMesh::setFamilyId(const char *familyName, int id); +MEDFileMesh::setFamilyInfo(const std::map& info); +MEDFileMesh::setGroupInfo(const std::map >&info); +MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false); +MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector& grps); +MEDFileMesh::setIteration(int it); +MEDFileMesh::setName(const char *name); +MEDFileMesh::setOrder(int order); +MEDFileMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); +MEDFileMesh::setTime(int dt, int it, double time); +MEDFileMesh::setTimeUnit(const char *unit); +MEDFileMesh::setTimeValue(double time); +MEDFileMesh::setUnivName(const char *name); +MEDFileMesh::simpleRepr() const; +MEDFileMesh::write(const char *fileName, int mode) const; +MEDFileMesh::write(med_idt fid) const; +///@} + +/*! \name Advanced API */ +///@{ +MEDFileMesh::clearNonDiscrAttributes() const; +///@} + +/*! \name Others... */ +///@{ +MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const char *familyNameToChange, const std::vector& newFamiliesNames); +MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid); +MEDFileMesh::MEDFileMesh(); +MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, int strt); +MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); +MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName); +MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); +MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector& newFamiliesNames); +MEDFileMesh::changeFamilyIdArr(int oldId, int newId); +MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab); +MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m); +MEDFileMesh::deepCpy() const; +MEDFileMesh::ensureDifferentFamIdsPerLevel(); +MEDFileMesh::getAllFamiliesIdsReferenced() const; +MEDFileMesh::getFamilyRepr(std::ostream& oss) const; +MEDFileMesh::getHeapMemorySize() const; +MEDFileMesh::getMaxFamilyIdInArrays() const; +MEDFileMesh::getMinFamilyId() const; +MEDFileMesh::getMinFamilyIdInArrays() const; +MEDFileMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const; +MEDFileMesh::getNumberOfNodes() const; +MEDFileMesh::getTheMaxFamilyId() const; +MEDFileMesh::getTheMinFamilyId() const; +MEDFileMesh::normalizeFamIdsMEDFile(); +MEDFileMesh::normalizeFamIdsTrio(); +MEDFileMesh::setFamilyIdUnique(const char *familyName, int id); +MEDFileMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); +MEDFileMesh::shallowCpy() const; +MEDFileMesh::synchronizeTinyInfoOnLeaves() const = 0; +MEDFileMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); +MEDFileMesh::writeLL(med_idt fid) const; +int MEDFileMesh::_order; +int MEDFileMesh::_iteration; +double MEDFileMesh::_time; +std::string MEDFileMesh::_dt_unit; +std::string MEDFileMesh::_name; +std::string MEDFileMesh::_univ_name; +std::string MEDFileMesh::_desc_name; +std::map > MEDFileMesh::_groups; +std::map MEDFileMesh::_families; +static const char MEDFileMesh::DFT_FAM_NAME[]; +///@} +} + diff --git a/doc/doxygen/interptheory.dox b/doc/doxygen/interptheory.dox index f53984c82..4fd32b8bb 100644 --- a/doc/doxygen/interptheory.dox +++ b/doc/doxygen/interptheory.dox @@ -8,8 +8,8 @@ For fields with polynomial representation on each cell, the components of the di \f] \f$W\f$ is called the \anchor interpolationmatrix interpolation matrix. -The objectives of interpolators is to compute the matrix W depending on their physical -properties (\ref IntExtFields) and their mesh discretisation (P0, P1,...). +The objective of interpolators is to compute the matrix W depending on their physical +properties (\ref IntExtFields) and their mesh discretisation (on cells P0, on nodes P1,...). \section ConsInterp Conservative interpolation @@ -42,9 +42,10 @@ fully overlapped by cells of S that is \sum_{S_j} Vol(T_i\cap S_j) = Vol(T_i),\hspace{1cm} and \hspace{1cm} \sum_{T_i} Vol(S_j\cap T_i) = Vol(S_j) \f] then the meshes S and T are said to be \b -overlapping and all the algorithms will return the same results. +overlapping. In this case the two formulas in a given column in the table below give the same +result. All intensive formulas result in the same output, and all the extensive formulas give also the same output. -The ideal interpolation algorithm should be conservative and respect the maximum principle. However such an algorithm can be impossible to design if the two meshes do not overlap. When the meshes do not overlap, using either \f$Vol(T_i)\f$ or \f$\sum_{S_j} Vol(T_i\cap S_j)\f$ in the formula one obtains an algorithm that respects either conservativity either the maximum principle (see the nature of field \ref TableNatureOfField "summary table"). +The ideal interpolation algorithm should be conservative and respect the maximum principle. However such an algorithm can be impossible to design if the two meshes do not overlap. When the meshes do not overlap, using either \f$Vol(T_i)\f$ or \f$\sum_{S_j} Vol(T_i\cap S_j)\f$ one obtains an algorithm that respects either the conservativity or the maximum principle (see the nature of field \ref TableNatureOfField "summary table"). \section InterpKerRemapInt Linear conservative remapping of P0 (cell based) fields @@ -109,7 +110,7 @@ given by the formula : \f] \section TableNatureOfField Summary -In the case of fields with P0 representation, if the meshes do not overlap the scheme is either conservative or maximum preserving (not both) and depending on the prioritised property and the \ref NatureOfField the interpolation coefficients take the following value +In the case of fields with a P0 representation (cell based) and when the meshes do not overlap, the scheme is either conservative or maximum preserving (not both). Depending on the \ref NatureOfField the interpolation coefficients take the following value: * * diff --git a/doc/doxygen/main.dox b/doc/doxygen/main.dox index a8e64c5b0..d4a1b6f13 100644 --- a/doc/doxygen/main.dox +++ b/doc/doxygen/main.dox @@ -18,9 +18,9 @@ library: \image html medlayers_70pc.png -The fondamentals consists in three atomic libraries: +The fondamentals consists in three atomic libraries: -- \ref medcoupling that describes DataStructures used for cross process exchange of meshes and fields. +- \ref medcoupling that describes DataStructures used for cross process exchange of meshes and fields. - \ref medloader that provides I/O functions to the MED file format - \ref interptools (INTERP_KERNEL + REMAPPER) that provides mathematical structures and algorithms for interpolation and @@ -40,25 +40,25 @@ you to deal with most standard use case of fields manipulation. The user guide can be found here: - User guide of the MED Graphical Interface + href="../../dev/MED/medop-userguide.html">User guide of the MED Graphical Interface (in french) You could also be interested to read the software specifications and requirements for this graphical module, and even the technical considerations for development: - Software - specifications and requirements of the MED Graphical Interface + href="../../dev/MED/medop-specifications.html">Software + specifications and requirements of the MED Graphical Interface (in french) - Developer guide of the MED Graphical Interface + href="../../dev/MED/medop-develguide.html">Developer guide of the MED Graphical Interface (in french) \section S3 A set of tools for file manipulation - Chapter \ref tools describes various tools based on MEDMEM that can -be helpful for handling MED files (conversion tools and splitting tools). +be helpful for handling MED files (conversion tools and splitting tools). -\section install Installation -The install procedure of the %MED SALOME module can handle a variety of configurations +\section install Installation +The install procedure of the %MED SALOME module can handle a variety of configurations to suit the needs of its user. Instructions for configuring and installing the module an be found in \ref medmem_install. diff --git a/doc/doxygen/medcoupling.dox b/doc/doxygen/medcoupling.dox index b8293f96e..80a67c7b6 100644 --- a/doc/doxygen/medcoupling.dox +++ b/doc/doxygen/medcoupling.dox @@ -43,7 +43,7 @@ For beginners in \ref medcoupling "MEDCoupling" world, it is advisable to read t \section MEDCouplingMeshes Common concept shared by all type of Meshes in MEDCoupling -A mesh has a the following properties : +A mesh has the following properties : - name - **a dimension (called mesh dimension) and only one** (it implies that \b all cells constituting @@ -227,23 +227,22 @@ It will be presented in this section common concept shared by the two classes to A \ref ParaMEDMEM::DataArray "DataArray" instance has an attribute **name**. **name** is particulary useful for \ref ParaMEDMEM::DataArray "DataArray" representing profiles, families, groups, fields in MEDLoader. -But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) is a bigger object. -Whatever the useage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names. +But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) in a bigger object. +Whatever the usage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names. \subsection MEDCouplingArrayBasicsTuplesAndCompo Raw data, tuples and components of DataArrays. The main goal of \ref ParaMEDMEM::DataArray "DataArray" is to store contiguous vector of atomical elements with same basic datatype (signed integers, double precision...). This vector of atomical elements is called **raw data** of \ref ParaMEDMEM::DataArray "DataArray". -The size of this vector of data is called, number of elements. So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to +The size of this vector of data is called "number of elements". So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to the product of the __number of elements__ * __constant size of DataType__ . -As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to stored vector fields, tensor fields, coordinate of nodes, the notion of components has been -added. +As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to store vector fields, tensor fields, coordinate of nodes, the notion of _components_ has been added. So, \ref ParaMEDMEM::DataArray "DataArrays" have an additional attribute that is number of components that represent the size of a contiguous set of atomical elements. -The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous in memory set of atomical elements having each same size. +The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous memory set of atomical elements having each same size. -The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, have each a length exactly equal to the number of components of +The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, have each a length exactly equal to the number of components of \ref ParaMEDMEM::DataArray "DataArray" storing it. Thus : @@ -256,8 +255,8 @@ Thus : N_{bytes}=N_{elements}*sizeof(DataType)=N_{tuples}*N_{components}*sizeof(DataType). \f] -In another words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples -would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix. +In other words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples +would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix. Typically in the **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" **number of tuples** is highly bigger than **number of components** ! @@ -324,7 +323,8 @@ An another way is to do that : \section MEDCouplingArraySteps1 Building an array from scratch in C++ -Here a description of typical usages to use \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays".\n +Here is a description of typical usages of \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays". + In this example we will create arrays with 12 tuples constituted each of 3 components. These arrays will be created using different ways.\n @@ -436,6 +436,20 @@ There are two types of comparison : - ParaMEDMEM::DataArrayInt::isEqualWithoutConsideringStr - ParaMEDMEM::DataArrayDouble::isEqualWithoutConsideringStr +\section MEDCouplingArrayFill Filling DataArray with values + +Both DataArrayDouble and DataArrayInt provide comfort methods that +fill the array with some values. These methods are: +- ParaMEDMEM::DataArrayInt::fillWithZero and + ParaMEDMEM::DataArrayDouble::fillWithZero which assigns zero to all + values in array. +- ParaMEDMEM::DataArrayInt::fillWithValue and + ParaMEDMEM::DataArrayDouble::fillWithValue which assigns a certain value to all + values in array. +- ParaMEDMEM::DataArrayInt::iota() and + ParaMEDMEM::DataArrayDouble::iota() which assigns incrementing values to all + values in array. + \section MEDCouplingArrayRenumbering Array renumbering Here is presented all it is necessary to know concerning renumbering. @@ -497,6 +511,9 @@ Method in new to old mode that works on bijective applications : Method in new to old mode that works on surjective applications : - \ref ParaMEDMEM::DataArrayDouble::selectByTupleId "DataArrayDouble::selectByTupleId" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe "DataArrayDouble::selectByTupleIdSafe" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleId2 "DataArrayDouble::selectByTupleId2" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleRanges "DataArrayDouble::selectByTupleRanges" \section MEDCouplingArrayApplyFunc Application of a function on DataArrayDouble instances. @@ -638,28 +655,32 @@ Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples contain \section IntExtFields Overview: intensive and extensive field -\c NatureOfField is an enum which helps determining some physical significance of the field and affects the choice of interpolation formula ( see \ref TableNatureOfField). +\c NatureOfField is an enum which helps determining some physical significance of the field and affects the choice of the interpolation formula (see \ref TableNatureOfField). It has five possible values: -- "NoNature", the default value, does not allow the use of interpolation tools +- "NoNature", the default value, does not allow the use of any interpolation tools - \ref TableNatureOfFieldExampleConservVol "ConservativeVolumic", for intensive field with the maximum principle favored over conservativity. Relevant for temperature, pression fields. +- \ref TableNatureOfFieldExampleRevIntegral "RevIntegral", for intensive field with the conservativity favored over maximum principle. Relevant for power density fields. + - \ref TableNatureOfFieldExampleIntegral "Integral", for extensive field with the maximum principle favored over conservativity. Relevant for power fields. - \ref TableNatureOfFieldExampleIntegralGlobConstraint "IntegralGlobConstraint", for extensive fields with conservativity favored over the maximum principle. Relevant for power fields. -- \ref TableNatureOfFieldExampleRevIntegral "RevIntegral", for intensive field with the conservativity favored over maximum principle. Relevant for power density fields. +The first two correspond to intensive fields, the last two correspond to extensive fields. -By an intensive field we mean a field that represent volumetric or intensive physical variable such as density (\f$kg.m^{-3}\f$), power density (\f$W.m^{-3}\f$), temperature (\f$K\f$) or pressure (\f$Pa\f$). -By extensive (or integral) field we mean a field that represents an extensive physical quantity sych as mass (\f$kg\f$), volume (\f$m^3\f$), a momentum (\f$kg.m.s^{-1}\f$) or power \f$(W\f$). -For fields with a P0 representation, conservativity formulas are different depending on whether the field is extensive or intensive (see \ref InterpKerP0P0Int and \ref InterpKerP0P0Ext). -In some cases such a non \ref MeshOverlap "overlapping meshes", it is impossible to fulfill both conservation and maximum principle during the interpolation. The nature of the fields determines the formula to be used for non overlapped cells and thus the property that we will be satisfied. -We consider that fields with P1 or P2 representations are necessarily intensive. +By an intensive field we mean a field that represent an intensive physical variable such as density (\f$kg.m^{-3}\f$), power density (\f$W.m^{-3}\f$), temperature (\f$K\f$) or pressure (\f$Pa\f$). Typically the physical value doesn't scale with the size of the underlying geometry. +By extensive (or integral) field we mean a field that represents an extensive physical quantity such as mass (\f$kg\f$), volume (\f$m^3\f$), a momentum (\f$kg.m.s^{-1}\f$) or power \f$(W\f$). +Typically the field value scales linearly with respect to the underlying geometry size. +For fields with a P0 representation (cell based), conservativity formulas are different depending on whether the field is extensive or intensive (see \ref InterpKerP0P0Int and \ref InterpKerP0P0Ext). +Those two notions are themselves split into two sub-categories. +Indeed in some cases (e.g. non \ref MeshOverlap "overlapping meshes"), it is impossible to fulfill both the conservation principle and the maximum principle during the interpolation. The nature of the fields determine the formula to be used for non overlapping cells and thus the property that we will be satisfied. +Finally we consider that fields with P1 or P2 representations are necessarily intensive. \section Usage -In order to employ the various \ref interptools, it is important to specify the nature of your field. -In case the sources and target meshes do not overlap different treatments will be employed, depending on the nature of the source and target fields. +In order to employ the various \ref interptools, you have to specify the nature of your field. +When the source and target meshes do not overlap, different treatments will be employed depending on the nature of the source and target fields. You can specify the nature of the field when you create a \ref medcoupling field with the following constructor: \code MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); @@ -725,11 +746,11 @@ and 9 nodes. You can notice that it is possible to mix cell types as long as the dimension of cell is exactly equal to meshDim to respect \ref MEDCouplingMeshes "this rule". -\subpage medcouplingcppexamplesUmeshStdBuild1 "Here the C++ implementation." +\subpage medcouplingcppexamplesUmeshStdBuild1 "Here is the C++ implementation." -\subpage medcouplingpyexamplesUmeshStdBuild1 "Here the Python implementation." +\subpage medcouplingpyexamplesUmeshStdBuild1 "Here is the Python implementation." -\section MEDCouplingUMeshNodalConnectivity How MEDCouplingUMesh stores its nodal connectivity. +\section MEDCouplingUMeshNodalConnectivity How MEDCouplingUMesh stores its nodal connectivity \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh class" stores its nodal connectivity into 2 arrays. @@ -852,4 +873,4 @@ The usage is simple : The virtual call to ParaMEDMEM::TimeLabel::updateTime change the behaviour of ParaMEDMEM::TimeLabel::getTimeOfThis it is a bug, so please notify the bug into the salome forum. -*/ \ No newline at end of file +*/ diff --git a/doc/doxygen/medcouplingexamples.doxy b/doc/doxygen/medcouplingexamples.doxy index fbf1a4767..794b307cd 100644 --- a/doc/doxygen/medcouplingexamples.doxy +++ b/doc/doxygen/medcouplingexamples.doxy @@ -1,11 +1,1835 @@ /*! -\page medcouplingcppexamples

MEDCoupling C++ examples

+\page medcouplingcppexamples MEDCoupling C++ examples + + +\anchor cpp_mcfielddouble_WriteVTK +

Writting fields in a VTK file

+ +In this example we +- create an 2D mesh and 3 fields on it, +- use +\ref ParaMEDMEM::MEDCouplingFieldDouble::WriteVTK "WriteVTK()" +to write all the fields and the mesh to a VTK file. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_WriteVTK_1 + + + +\anchor cpp_mcfielddouble_MaxFields +

Getting maximal and minimal fields

+ +In this example we +- create two fields with two tuples per two components, +- use +\ref ParaMEDMEM::MEDCouplingFieldDouble::MaxFields "MaxFields()" +to get a field holding maximal values of the two fields. +- use +\ref ParaMEDMEM::MEDCouplingFieldDouble::MinFields "MinFields()" +to get a field holding minimal values of the two fields. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_MaxFields_1 + + +\anchor cpp_mcfielddouble_MergeFields +

Concatenating fields

+ +In this example we +- create an 1D mesh and a field on it, +- make a deep copy of the mesh and the field, +- translate the mesh and the field, +- use two variants of +\ref ParaMEDMEM::MEDCouplingFieldDouble::MergeFields "MergeFields()" +to create one field from the two by concatenating them and their meshes. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_MergeFields_1 +The result field is twice "longer" than \b field1. + + + +\anchor cpp_mcfielddouble_substractInPlaceDM +

Subtracting field on different meshs

+ +We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped +in the two meshes.
+And we make two fields on these meshes, so that fields values to equal to node +coordinates of the underlying meshes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1 +We are going to subtract \b field2 from \b field1, though they are on +different meshes. +\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" +allows us doing this. We use a mesh comparison level \b levOfCheck = 10 that allows +subtracting fields on meshes with different node arrays.
+\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2 +After applying +\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" +the both fields lie on \b mesh2. As +\ref ParaMEDMEM::MEDCouplingFieldDouble::substractInPlaceDM "substractInPlaceDM()" +permutes values of \b field1 before value subtraction, and thus \b field1 becomes +equal to \b feild2, hence their subtraction results in a zero field. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3 + + + +\anchor cpp_mcfielddouble_changeUnderlyingMesh +

Changing the underlying mesh

+ +We make two meshes in 1D space with no cells and 4 nodes. Nodes #0 and #2 are swapped +in the two meshes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1 +We are going to use +\ref ParaMEDMEM::MEDCouplingFieldDouble::changeUnderlyingMesh "changeUnderlyingMesh()" +to set \b mesh2 instead of \b mesh1 as a support of a field.
+We use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic "fillFromAnalytic()" +to make a field on nodes of \b mesh1, so that its values to equal to node coordinates. +Then we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::changeUnderlyingMesh "changeUnderlyingMesh()" +to change the underlying mesh of the \b field. +(We use a mesh comparison level \b levOfCheck = 10 that allows substituting meshes with +different node arrays.) As a result, we expect that values of the \b field are also +permuted same as nodes of the two meshes, and thus its values become equal to the +array \b coords2. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2 + + +\anchor cpp_mcfielddouble_applyFunc_same_nb_comp +

Changing a field using a formular

+ +We create a 2D vector field with 2 tuples and we want to transform this +field using a formular using +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(const char *func) "applyFunc()". +The formular \b func is applied each atomic value of the \b field. We want to change +the \b field as follows. (In \b func, we use the variable "v" to refer to an atomic field value). +- Component #0 = component #0 (remains the same); hence "IVec * v" in \b func. +- Component #1 = component #1 ^ 2; hence "JVec * v*v". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1 +Now we ascertain that the result field is as we expect. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2 + + + +\anchor cpp_mcfielddouble_applyFunc3 +

Changing a field using a formular

+ +We create a 2D vector field with 2 values (vectors) and then we transform this +field into a 3D vector field by applying a formular to values of the 2D field +using +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc3() "applyFunc3()". +The formular \b func is applied to components of each vector of the \b field. We want +the \b field to have 3 components computed as follows. (In \b func, we refer to the +first component of a field value using the variable "a", and to the second component, using +the variable "b", as we define it by \b varNamesVec). +- Component #0 = the second vector component; hence "IVec * b" in \b func. +- Component #1 = the first vector component; hence "JVec * a". +- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc3_1 +Now we ascertain that the result field is as we expect. We check the second vector of +the \b field. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc3_2 + + + +\anchor cpp_mcfielddouble_applyFunc2 +

Changing a field using a formular

+ +We create a 2D vector field with 2 values (vectors) and then we transform this +field into a 3D vector field by applying a formular to values of the 2D field +using +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) "applyFunc2()". +Note that we set component info the \b array ("a" and "b" ) which will be used to refer to +corresponding components within a function. +The formular \b func is applied to components of each vector of the \b field. We want +the \b field to have 3 components computed as follows. (In \b func, we refer to the +first component of a field value using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second vector component; hence "IVec * b" in \b func. +- Component #1 = the first vector component; hence "JVec * a". +- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc2_1 +Now we ascertain that the result field is as we expect. We check the second vector of +the \b field. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc2_2 + + + +\anchor cpp_mcfielddouble_applyFunc +

Changing a field using a formular

+ +We create a 2D vector field with 2 values (vectors) and then we transform this +field into a 3D vector field by applying a formular to values of the 2D field +using +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) "applyFunc()". +The formular \b func is applied to components of each vector of the \b field. We want +the \b field to have 3 components computed as follows. (In \b func, we refer to the +first component of a field value using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second vector component; hence "IVec * b" in \b func. +- Component #1 = the first vector component; hence "JVec * a". +- Component #2 = a vector magnitude; hence "KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_1 +Now we ascertain that the result field is as we expect. We check the second vector of +the \b field. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_2 + + + +\anchor cpp_mcfielddouble_applyFunc_val +

Filling a field with a value

+ +We want to transform a 2D vector field to a 3D vector field so that all values to be +equal to a certain value. First, we create the 2D mesh and the vector field on it. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_val_1 +Finally we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) "applyFunc()" +to change the number of components and all field values. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_applyFunc_val_2 +As a result, number of tuples in the field equals to the number of cells in the mesh, +and number of components becomes equal to 3 as required. + + +\anchor cpp_mcfielddouble_fillFromAnalytic3 +

Filling a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1 +Now we create a field on cells and use +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic2 "fillFromAnalytic2()" +to fill it +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want the \b field +to have 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3 + + + +\anchor cpp_mcfielddouble_fillFromAnalytic2 +

Filling a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to +corresponding coordinates within a function. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1 +Now we create a field on cells and use +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic2 "fillFromAnalytic2()" +to fill it +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want the \b field +to have 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3 + + +\anchor cpp_mcfielddouble_fillFromAnalytic +

Filling a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1 +Now we create a field on cells and use +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) "fillFromAnalytic()" +to fill it +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want the \b field to have + 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 to check that values of the second +tuple (#1) are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3 + + +\anchor cpp_mcfielddouble_getValueOn_time +

Getting a field value at some point at certain time

+ +First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh +constituted by 4 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1 +Then we create a scalar field on cells, whose values vary linearly in time. +We set all field values at a start time to be equal 10.0 using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". +And we set all field values at an end time to be equal 20.0 by doubling the start +time array. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2 +Now, we want to get a field value at a point [0,0] at a middle time between the start +and end times. We expect the returned value to be equal to an average of 10. and 20. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3 + + +\anchor cpp_mcfielddouble_getValueOnMulti +

Getting field values at some points

+ +First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh +constituted by 4 cells. Then we create a scalar field on cells using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1 +Now, we want to retrieve all field values using +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()". +The field values relate to cells, hence we will use cell barycenters as a parameter of +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()". +We expect that the double array returned +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti "getValueOnMulti()" +is equal to that stored by \b field. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2 + + + +\anchor cpp_mcfielddouble_getValueOn +

Getting a field value at a point

+ +First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh +constituted by 4 cells. Then we create a scalar field on cells using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_1 +Now, we want to retrieve all field values using +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()". +The field values relate to cells, hence we will use cell barycenters to get a field +value at each cell. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOn_2 +We collected all values returned by +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOn "getValueOn()" in an array, so +that we can ascertain that the array of returned values is same as that stored by \b +field. + + + +\anchor cpp_mcfielddouble_getValueOnPos +

Getting a value of field lying on a structured mesh

+ +First, we create a supporting structured mesh. We create a 2x2 Cartesian mesh +constituted by 4 cells. Then we create a scalar field on cells using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1 +Now, we retrieve a field value relating to the cell #3 (this cell has a structured indexed +(1,1)). For that we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::getValueOnPos "getValueOnPos()" where we +pass the structured indexed of the cell: 1,1,-1 (the last index is meaningless as the +mesh is 2D). +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2 +After all we ascertain that the returned value corresponds to the formular used for +the field creation. Namely that the value equals to the sum of components of +barycenter of cell #3. + + + +\anchor cpp_mcfielddouble_renumberNodes +

Permuting a field on nodes

+ +First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 +Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh +is not suitable for +\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberNodes "renumberNodes()" as its + nature does not imply node renumbering. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_1 +Then we create a field on nodes using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()", +such that its values to coincide with coordinates of field location points that are + nodes in our case (as our field is \ref ParaMEDMEM::ON_NODES "ON_NODES"). +At last we ascertain that field values are equal to node coordinates. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_2 +Now, we are going to reverse order of nodes using +\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberNodes "renumberNodes()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberNodes_3 +As a result, the underlying mesh of \b field is changed and its nodes are also + renumbered. +And the field values are still equal to node coordinates of the renumbered \b mesh2. + + + +\anchor cpp_mcfielddouble_renumberCells +

Permuting a field on cells

+ +First, we create a supporting 2D mesh constituted by 4 cells. We create a 2x2 +Cartesian mesh and then convert it to an unstructured one, since the Cartesian mesh +is not suitable for +\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberCells "renumberCells()" as its + nature does not imply cell renumbering. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_1 +Then we create a field on cells using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()", +such that its values to coincide with coordinates of field location points that are + cell barycenters in our case (as our field is \ref ParaMEDMEM::ON_CELLS "ON_CELLS"). +At last we ascertain that field values are equal to cell barycenters. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_2 +Now, we are going to reverse order of cells using +\ref ParaMEDMEM::MEDCouplingFieldDouble::renumberCells "renumberCells()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_renumberCells_3 +As a result, the underlying mesh of \b field is changed and its cells are also + renumbered. +And the field values are still equal to cell barycenters of the renumbered \b mesh2. + + + +\anchor cpp_mcfielddouble_buildNewTimeReprFromThis +

Getting a field copy with different time discretization

+ +First, we create a supporting 2D mesh and a field on it got using +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic "fillFromAnalytic()". +\ref MEDCouplingTemporalDisc "Time discretization" of this field is +\ref ParaMEDMEM::ONE_TIME "ONE_TIME". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1 +Now we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis "buildNewTimeReprFromThis()" +to get a copy of \b field1 whose time discretization is +\ref ParaMEDMEM::NO_TIME "NO_TIME". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2 + + +\anchor cpp_mcmesh_fillFromAnalytic3 +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3 "fillFromAnalytic3()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3 + + + +\anchor cpp_mcmesh_fillFromAnalytic2 +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to +corresponding coordinates within a function. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2 "fillFromAnalytic2()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3 + + +\anchor cpp_mcmesh_fillFromAnalytic +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic "fillFromAnalytic()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_3 + + +\anchor cpp_mccmesh_getCoordsAt +

Getting node coordinates

+ +We create an 1D Cartesian mesh and retrieves node coordinates using +\ref ParaMEDMEM::MEDCouplingCMesh::getCoordsAt "getCoordsAt()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingCMesh_getCoordsAt_1 + + + +\anchor cpp_mcumesh_areCellsIncludedIn +

Cells correspondence in two meshes

+ +First, we create a 2D \b mesh1 with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1 +Then we create a \b mesh2 which includes cells #4, #2 and #0 of \b mesh1. The two meshes +share the same node coordinates array. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2 +Now we ascertain that +- \ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()" +detects that all cells of \b mesh2 are present in \b mesh1, +- the correspondence array \b corr2to1, which gives cell ids of \b mesh2 within +\b mesh1, is equal to the array \b cells2 which selected cells from \b mesh1 for creation +of \b mesh2. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3 +Now we apply +\ref ParaMEDMEM::MEDCouplingUMesh::areCellsIncludedIn "areCellsIncludedIn()" +in a reverse direction and ascertain that it returns \c false. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4 +The contents of the correspondence +array \b corr1to2 [2, 3, 1, 4, 0] means the following. +- The cell #0 of \b mesh1 is equal to the cell #2 (== \b corr1to2[ 0 ]) of \b mesh2. +- The cell #1 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 1 ] >= \b mesh2->getNumberOfCells()). +- The cell #2 of \b mesh1 is equal to the cell #1 (== \b corr1to2[ 2 ]) of \b mesh2. +- The cell #3 of \b mesh1 is missing from \b mesh2 (as \b corr1to2[ 3 ] >= \b mesh2->getNumberOfCells()). +- The cell #4 of \b mesh1 is equal to the cell #0 (== \b corr1to2[ 4 ]) of \b mesh2. + + +\anchor cpp_mcumesh_checkDeepEquivalWith +

Deep comparison of meshes

+ +First, we create two 2D meshes with two triangles, so that +- their nodes are almost same but permuted, +- the first triangle is based exactly on the same nodes (taking the permutation into account), +- an order of nodes in the second triangle is changed. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1 +Then we check that +- \ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalWith "checkDeepEquivalWith()" +considers the meshes equal (i.e. it does not throw any exception) if it is called with a cell +comparison policy \b cellCompPol == 1 +- mapping from \b mesh1 to \b mesh2 for both nodes and cells is as expected. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2 +Next we ascertain that +\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()" +consider \b mesh1 and \b mesh2 different as they do not share the same nodal connectivity +array.
+After that we make the meshes share the node coordinates array and insert new +triangles based on the same nodes but in different order. This is to ascertain that +\ref ParaMEDMEM::MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith "checkDeepEquivalOnSameNodesWith()" +called with the weakest cell comparison policy considers the meshes equal. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3 + + + +\anchor cpp_mcumesh_getPartBarycenterAndOwner +

Getting barycenters of cells

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner "getPartBarycenterAndOwner()" to get +barycenters of all but the first cell. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_3 +The returned array contains 4 tuples per 2 components. + + +\anchor cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells +

Fixing orientation of "extruded" volumes

+ +First, we create a mesh with 2 incorrectly oriented "extruded" volumes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1 +Now we check that +\ref ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells "findAndCorrectBadOriented3DExtrudedCells()" +finds and fixes the reversed cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2 + + +\anchor cpp_mcumesh_arePolyhedronsNotCorrectlyOriented +

Fixing orientation of polyhedra

+ +First, we create a mesh with 2 polyhedra, one of which is incorrectly oriented. We create +two "extruded" polyhedra and then convert them to correctly defined polyhedra. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1 +Now we check that +\ref ParaMEDMEM::MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented "arePolyhedronsNotCorrectlyOriented()" +finds one reversed cell. After that we fix it using +\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectlyPolyhedrons "orientCorrectlyPolyhedrons()" and +re-check the orientation of polyhedra. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2 + + +\anchor cpp_mcumesh_are2DCellsNotCorrectlyOriented +

Fixing orientation of faces

+ +First, we create a 2D mesh in 3D space with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is +reversed comparing with others. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1 +Now we check that +\ref ParaMEDMEM::MEDCouplingUMesh::are2DCellsNotCorrectlyOriented "are2DCellsNotCorrectlyOriented()" +finds one reversed face. After that we fix the incorrectly oriented cell using +\ref ParaMEDMEM::MEDCouplingUMesh::orientCorrectly2DCells "orientCorrectly2DCells()" and +re-check the orientation of cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2 + + +\anchor cpp_mcumesh_getCellsContainingPoints +

Finding cells containing a point (multi-point case)

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1 +Then we use +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoints "getCellsContainingPoints()" to +get cells in contact with tree points. Two of them are in contact with some cells and one is not. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2 +The contents of the result arrays \b cells ([4, 0, 1]) and \b cellsIndex ([0, 0, 1, 3]) +mean the following. +- Point #0 is in contact with none (== \b cellsIndx[1] - \b cellsIndx[0]) cell. +- Point #1 is in contact with 1 (== \b cellsIndx[2] - \b cellsIndx[1]) cell whose id is #4 + (== \b cells[ \b cellsIndx[ 1 ]]). +- Point #2 is in contact with 2 (== \b cellsIndx[3] - \b cellsIndx[2]) cells whose ids are #0 + (== \b cells[ \b cellsIndx[ 2 ]]) and #1 (== \b cells[ \b cellsIndx[ 2 ] + 1 ]). + + +\anchor cpp_mcumesh_getCellsContainingPoint +

Finding cells containing a point

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1 +Then we use +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsContainingPoint "getCellsContainingPoint()" to +get cells in contact with a small ball (point with precision) located near the node #4 and +shifted from this node by its radius \b eps. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2 +Since the node #4 is shared by all cells, size of the vector \b cellIds must be equal to +the number of cells in \b mesh. + +\anchor cpp_mcumesh_buildPartOrthogonalField +

Getting normals of cells

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is +reversed. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField "buildPartOrthogonalField()" to get +normal vectors to the cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2 + + + +\anchor cpp_mcumesh_getPartMeasureField +

Getting volumes of cells

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. Orientation of the cell #1 is +reversed. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" to get +volumes of all but the first cell. If we call +\ref ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField "getPartMeasureField()" with \b +isAbs == \c true, the area of the cell #1 is returned positive, else, negative that +reflects its inverse orientation. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getPartMeasureField_2 + + + +\anchor cpp_mcumesh_getCellsInBoundingBox +

Getting cells using the bounding box

+ +First, we create a 2D mesh with 1 TRI3 cell. Bounding box of this cell is [0.,0., 1.,1]. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1 +Now we check how +\ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" +searches for cells using the bounding box. We use a bounding box touching the bounding box +of the sole cell at one point (1.,1.). +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2 +If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is +called with parameter \b eps == 0.0, the cell is not found because the two bounding boxes +(one of the cell and the one passed as parameter) do not overlap.
+If \ref ParaMEDMEM::MEDCouplingUMesh::getCellsInBoundingBox "getCellsInBoundingBox()" is +called with parameter \b eps == 0.1, the cell is found because \b eps is used to increase +the bounding box of the cell and thus the two bounding boxes intersect each other.
+ +\anchor cpp_mcumesh_renumberNodesInConn +

Renumbering nodes in the connectivity array

+ +First, we create a 2D mesh with 1 QUAD4 cell and with undefined coordinates of nodes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn()" +to get the following nodal connectivity of a sole cell: 0,1,2,3. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2 +\b old2newIds array defines how node ids are changed: +- new id of node #0 is -1, +- new id of node #1 is 3, +- new id of node #2 is 4, +- new id of node #3 is 1, +- new id of node #4 is 0. + +\anchor cpp_mcumesh_renumberNodes +

Renumbering nodes

+ +First, we create a 2D mesh with 4 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_1 +Next, we use +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()" +to permute nodes so that +- old node #0 becomes #2, +- old node #1 remains #1, +- old node #2 becomes #0, +- old node #3 is removed. + +Number of nodes becomes 3. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_2 + +Next we compare behavior of +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()" and that of +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" which, in contrast to +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes "renumberNodes()", +moves merged nodes to their barycenter.
+We set #2 as new id of old node #3 and expect that +\ref ParaMEDMEM::MEDCouplingUMesh::renumberNodes2 "renumberNodes2()" moves old nodes #0 +and #3 to their barycenter (-0.3,0.0) which becomes position of node #2.
+\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_renumberNodes_3 + + +\anchor cpp_mcumesh_findBoundaryNodes +

Getting boundary nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" to get ids +of boundary nodes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2 +\ref ParaMEDMEM::MEDCouplingUMesh::findBoundaryNodes "findBoundaryNodes()" returns all +node ids except the node #4 which is in the middle of \b mesh. + + +\anchor cpp_mcumesh_buildBoundaryMesh +

Getting a bounding mesh

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()" to get a mesh +of lower dimension bounding \b mesh. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2 +Depending on the value of a parameter, +\ref ParaMEDMEM::MEDCouplingUMesh::buildBoundaryMesh "buildBoundaryMesh()" +creates the mesh sharing the node coordinates array with \b mesh or not. + + +\anchor cpp_mcumesh_buildFacePartOfMySelfNode +

Retrieving a lower dimension mesh based on given nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1 +In the following code we retrieve nodes of the cell #0 an then we call +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" +twice with these nodes and with varying last parameter \b allNodes as input. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2 +
If the last parameter is \c true +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks +for segements whose all nodes are given to it, hence it finds segments bounding the cell #0 only. +
If the last parameter is \c false +\ref ParaMEDMEM::MEDCouplingUMesh::buildFacePartOfMySelfNode "buildFacePartOfMySelfNode()" looks +for any segment whose nodes are given to it, hence it adds more segments to \b mesh2. + + +\anchor cpp_mcumesh_buildPartOfMySelfNode +

Copying cells selected by nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1 +In the following code we retrieve nodes of the cell #0 an then we call +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" +twice with these nodes and with varying last parameter \b allNodes as input. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2 +
If the last parameter is \c true +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks +for cells whose all nodes are given to it, hence it finds the cell #0 only. +
If the last parameter is \c false +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelfNode "buildPartOfMySelfNode()" looks +for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all +cells share the node #4. + + +\anchor cpp_mcumesh_getCellIdsLyingOnNodes +

Getting cells by nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1 +In the following code we retrieve nodes of the cell #0 an then we call +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" +twice with these nodes and with varying last parameter \b allNodes as input. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2 +
If the last parameter is \c true +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks +for cells whose all nodes are given to it, hence it finds the cell #0 only. +
If the last parameter is \c false +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsLyingOnNodes "getCellIdsLyingOnNodes()" looks +for any cell whose nodes are given to it, hence it finds all cells of \b mesh because all +cells share the node #4. + + + +\anchor cpp_mcumesh_getCellIdsFullyIncludedInNodeIds +

Getting cells by nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1 +In the following code we retrieve nodes of two cells an then we use +\ref ParaMEDMEM::MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds +"getCellIdsFullyIncludedInNodeIds()" to find these cells by their nodes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2 + + +\anchor cpp_mcumesh_buildPartOfMySelf +

Getting a part of mesh

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelf "buildPartOfMySelf()" to get a mesh +containing only two cells of \b mesh. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2 + + +\anchor cpp_mcumesh_mergeNodes +

Merging equal nodes

+ +First, we create a 2D mesh with 1 QUAD4 and 2 TRI3 cells. The cells are based on 6 nodes +of which 2 nodes fully coincide (#3 and #4) and 3 nodes are equal with precision 0.003. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_1 +Now we merge node duplicates using +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and check values it returns. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_2 +Contents of \b arr shows ids of old nodes after the merging. The nodes considered equal +one to the other have the same id in \b arr. + +Next we compare behavior of +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" and that of +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" which, in contrast to +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()", +moves merged nodes to their barycenter.
We expect that +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes2 "mergeNodes2()" moves old nodes #0, #2 +and #5 to their barycenter equal to position of node #2.
+First we check that +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes()" does not move nodes +coincident with the node #2 to the position of node #2, and then we check that +\ref ParaMEDMEM::MEDCouplingUMesh::mergeNodes "mergeNodes2()" does move. +(We check only the second (Y) component of node coordinates since the first component of +these nodes is exactly same.) +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_mergeNodes_3 + + + +\anchor cpp_mcumesh_zipConnectivityTraducer +

Removing cell duplicates

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells, so that +- the cell #2 has the same nodal connectivity as the cell #1 does, +- the cell #3 has the same nodal connectivity as the cell #0 does, +- the cell #4 is based on the same nodes as the cell #0 but nodes order is different. + +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1 +Now we use +\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()" +to remove duplicate cells. Then we check that two cells, having exactly same nodal +connectivity with other cells, have been removed. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2 +Contents of \b arr shows ids of cells after duplicates removal. If a value (cell id) +equals to its index in \b arr, this means that the cell is not a duplicate of any cell +with lower id. Else, the value gives a cell id to which this cell is equal.
+Thus, the cells #0 and #1 have no preceding equal cell since \b arr[i] == i.
+The cell #2 equals to the cell #1 (== \b arr[2] ).
+The cell #3 equals to the cell #0 (== \b arr[3] ).
+The cell #4 has no equal cell. This is because the cell comparison technique specified +when we called +\ref ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer "zipConnectivityTraducer()" +was 0 ("exact"), if we had used the technique 2 ("nodal"), \b arr[4] would be 0. + + + +\anchor cpp_mcumesh_zipCoordsTraducer +

Removing unused nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1 +Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref +ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" to remove unused +nodes from \b mesh2. +\ref ParaMEDMEM::MEDCouplingUMesh::zipCoordsTraducer "zipCoordsTraducer()" returns an array +with -1 for unused nodes and new ids for used ones. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2 + + + +\anchor cpp_mcumesh_getNodeIdsInUse +

Retrieving unused nodes

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1 +Now we create \b mesh2 including all nodes but only two cells of \b mesh, and we use \ref +ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to get nodes of \b mesh2 +used in its two cells. +\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" returns an array +with -1 for unused nodes and new ids for used ones. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2 +Now we use \b newNbOfNodes returned by +\ref ParaMEDMEM::MEDCouplingUMesh::getNodeIdsInUse "getNodeIdsInUse()" to convert \b arr +to "New to Old" mode. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3 + + +\anchor cpp_mcumesh_convertToPolyTypes +

Conversion of cells to "poly" types

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1 +Now we convert cells #1 and #3 to type POLYGON and check the result +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2 + + +\anchor cpp_mcumesh_buildDescendingConnectivity2 +

Retrieving the descending connectivity with orientation

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1 +Now we get and check the descending connectivity. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2 +Here we get connectivity of the cell #2 (#3 in FORTRAN mode) of \b mesh2 to see how +mutual orientation of cells in \b mesh and \b mesh2 is defined. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3 +The contents of the result arrays \b desc and \b descIndx mean the following. +- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0]) + segments (SEG2) of \b mesh2 whose ids in FORTRAN mode are + - #1 (== \b desc[ \b descIndx[ 0 ]]), + - #2 (== \b desc[ \b descIndx[ 0 ] + 1 ]), + - #3 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and + - #4 (== \b desc[ \b descIndx[ 0 ] + 3 ]). +
Ids are positive since order of nodes in the corresponding cells of \b mesh and \b mesh2 + are same. For example nodes of SEG2 #3 are [4,1] and nodes of QUAD4 #0 are [0,3,\b 4,\b 1]. +- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of + \b mesh2 whose ids in FORTRAN mode are: + - #-3 (== \b desc[ \b descIndx[ 1 ]]), + - #5 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and + - #6 (== \b desc[ \b descIndx[ 1 ] + 2 ]). +
The id -3 means that order of nodes in SEG2 #3 ([4,1]) is different from the order of + these nodes in TRI3 #1: [\b 1,\b 4,2]. +- etc. + +The contents of the result arrays \b revDesc and \b revDescIndx mean the following. +- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b + mesh whose id is: + - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]). +- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b + mesh whose ids are: + - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and + - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]). +- etc. + + + +\anchor cpp_mcumesh_buildDescendingConnectivity +

Retrieving the descending connectivity

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1 +Now we get and check the descending connectivity. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2 +The contents of the result arrays \b desc and \b descIndx mean the following. +- The cell #0 of \b mesh (QUAD4) is bound by 4 (== \b descIndx[1] - \b descIndx[0]) + segments (SEG2) of \b mesh2 whose ids are + - #0 (== \b desc[ \b descIndx[ 0 ]]), + - #1 (== \b desc[ \b descIndx[ 0 ] + 1 ]), + - #2 (== \b desc[ \b descIndx[ 0 ] + 2 ]) and + - #3 (== \b desc[ \b descIndx[ 0 ] + 3 ]). +- The cell #1 of \b mesh (TRI3) is bound by 3 (== \b descIndx[2] - \b descIndx[1]) segements of + \b mesh2 whose ids are: + - #2 (== \b desc[ \b descIndx[ 1 ]]), + - #4 (== \b desc[ \b descIndx[ 1 ] + 1 ]) and + - #5 (== \b desc[ \b descIndx[ 1 ] + 2 ]). +- etc. + +The contents of the result arrays \b revDesc and \b revDescIndx mean the following. +- The cell #0 of \b mesh2 (SEG2) bounds 1 (== \b revDescIndx[1] - \b revDescIndx[0]) cell of \b + mesh whose id is: + - # 0 (== \b revDesc[ \b revDescIndx[ 0 ]]). +- The cell #1 of \b mesh2 bounds 2 (== \b revDescIndx[2] - \b revDescIndx[1]) cells of \b + mesh whose ids are: + - # 0 (== \b revDesc[ \b revDescIndx[ 1 ]]) and + - # 1 (== \b revDesc[ \b revDescIndx[ 1 ] + 1 ]). +- etc. + + +\anchor cpp_mcumesh_getReverseNodalConnectivity +

Getting the reverse nodal connectivity

+ +First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1 +Now we get and check its reverse nodal connectivity. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2 +The contents of the result arrays mean the following. +- Node #0 is shared by 1 (== \b revNodalIndx[1] - \b revNodalIndx[0]) cell whose id is #0 + (== \b revNodal[ \b revNodalIndx[ 0 ]]). +- Node #1 is shared by 2 (== \b revNodalIndx[2] - \b revNodalIndx[1]) cells whose ids are #0 + (== \b revNodal[ \b revNodalIndx[ 1 ]]) and #1 (== \b revNodal[ \b revNodalIndx[ 1 ] + 1 ]). +- etc. + +\anchor cpp_mcpointset_scale +

Scaling the mesh

+ +First, we create a 2D mesh with 4 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_1 +Then we scale it by a factor of 2 with a center (0.,0.). +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_2 +Finally we check that all node coordinates have changed by more than 0.9. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_scale_3 + + + + +\anchor cpp_mcpointset_translate +

Translating the mesh

+ +First, we create a 2D mesh with 4 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_1 +Then we translate it by a vector (1.,1.). +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_2 +Finally we check that all node coordinates have changed by more than 0.9. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_translate_3 + + + +\anchor cpp_mcpointset_rotate +

Rotating the mesh

+ +First, we create a 2D mesh with 4 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_1 +Then we rotate it around a point (0.,0.) by 90 degrees clockwise. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_2 +Next, we make a 3D mesh from the 2D one and rotate it around the Z axis by 90 degrees +counter-clockwise. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_3 +Finally we transform the mesh back to 2D space and check that all nodes get back to the +initial location. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_rotate_4 + +\anchor cpp_mcpointset_getBoundingBox +

Getting a minimum box bounding nodes

+ +First, we create a 3D mesh with 2 nodes, so that the first one has minimal coordinates and +the second one has maximal coordinates. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_1 +Now we get a bounding box enclosing these nodes. This bounding box should contain +coordinates of our two nodes (but in "no interlace" mode), as the nodes coincide with +points returned by the bounding box. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getBoundingBox_2 + + +\anchor cpp_mcpointset_getnodeidsnearpoint +

Getting nodes close to a point

+ +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh +"MEDCouplingUMesh" with 5 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1 +Now we define an array of coordinates of a point close to nodes #0, #2 and #4. + +Thus we expect that +\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoint "getNodeIdsNearPoint()" that +we are going to use, +if called with \b eps = 0.003, would return ids of nodes #0, #2 and #4. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2 + + +\anchor cpp_mcpointset_getnodeidsnearpoints +

Getting nodes close to some points

+ +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh +"MEDCouplingUMesh" with 7 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1 +Now we define an array of coordinates of 3 points near which we want to find nodes of the mesh. +- Point #0 is at distance 0.001 from the node #1. +- Point #1 is rather far from all nodes. +- Point #2 is close to nodes #3, #4 and #5. + +Thus we expect that +\ref ParaMEDMEM::MEDCouplingPointSet::getNodeIdsNearPoints "getNodeIdsNearPoints()" that +we are going to use, +if called with \b eps = 0.003, would return ids of close nodes #1, #3, #4 and #5. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2 +\b idsIndex returns [0, 1, 1, 4] which means that: +- Point #0 is close to 1 (== \b idsIndex[1] - \b idsIndex[0]) node whose id is +\b ids[ \b idsIndex[ 0 ]]. +- Point #1 is close to 0 (== \b idsIndex[2] - \b idsIndex[1]) nodes. +- Point #2 is close to 3 (== \b idsIndex[3] - \b idsIndex[2]) nodes whose ids are +\b ids[ \b idsIndex[ 2 ]], \b ids[ \b idsIndex[ 2 ] + 1 ] and \b ids[ \b idsIndex[ 2 ] + 2 ]. + + +\anchor cpp_mcpointset_findcommonnodes +

Finding coincident nodes

+ +First, we create a mesh with 6 nodes, of which two nodes (#3 and #4) are fully coincident +and 3 nodes (#0, #2 and #5) have distance less than 0.004 between them. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_1 +Then, we use \ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" to find +coincident nodes, and check that (1) calling +\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes()" with \b prec +== 1e-13 finds the two fully coincident nodes only and (2) +\ref ParaMEDMEM::MEDCouplingPointSet::findCommonNodes() "findCommonNodes"(0.004) finds 5 +equal nodes. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_findCommonNodes_2 + +\anchor cpp_mcpointset_getcoordinatesofnode +

Getting coordinates of a node

+ +The following code creates a 2D \ref ParaMEDMEM::MEDCouplingUMesh +"MEDCouplingUMesh" with 3 nodes and no cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1 +Here we get coordinates of the second node and check its two coordinates. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2 + +\anchor cpp_mcdataarrayint_getTuple +

Getting a tuple of DataArrayInt

+ +In this simple example we create an array of integers arranged into 3 +tuples per 2 components, and finally print the second tuple. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_1 +The output is +
 [9, 10] 
+Note that we can traverse all tuples in the array by simply iterating +over it as the code below does. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_2 +Its output follows. +
+(7, 8)
+(9, 10)
+(11, 12)
+
+ +\anchor cpp_mcdataarrayint_buildpermutationarr +

Building a permutation array

+ +Here we create two arrays containing same values but in different order and then we use +\ref ParaMEDMEM::DataArrayInt::buildPermutationArr "DataArrayInt::buildPermutationArr()" to get +an array showing in what places the values of \b b array are located in \b a array. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_buildPermutationArr_1 +The result array \b c contains [1,0,4,2,3]. + +

Inverting renumbering maps

+\anchor cpp_mcdataarrayint_invertarrayo2n2n2o +

invertArrayO2N2N2O()

+ +In this example we create a DataArrayInt containing a renumbering map in +"Old to New" mode, convert it into the renumbering map in "New to Old" mode and check the +result. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayO2N2N2O_1 + +\anchor cpp_mcdataarrayint_invertarrayn2o2o2n +

invertArrayN2O2O2N()

+ +In this example we create a DataArrayInt containing a renumbering map in +"New to Old" mode, convert it into the renumbering map in "Old to New" mode and check the +result. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayN2O2O2N_1 + + + +\anchor cpp_mcdataarraydouble_getidsinrange +

Finding values in range in DataArrayDouble

+ +In this example we create an array \b da containing same values as ones returned by +\c range( \c 10 ). Then we get an array of indices of values of \b da being in +range [ 2.5, 6 ]. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_getIdsInRange_1 +As result contents of the array \b da2 are as follows. +
+    Tuple #0 : 3
+    Tuple #1 : 4
+    Tuple #2 : 5
+    Tuple #3 : 6
+
+ + +\anchor py_mcdataarraydouble_setselectedcomponents +

Set part of values of DataArrayDouble

+

setSelectedComponents()

+First, we create a 'source' array. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents1 +Now we create a larger zero array and assign the array \b da into it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents2 +As result contents of the array \b dv are as follows. +
+Info of components : "a2"   "a1"   "v3"   "v4"   
+    Tuple #0 : 2 1 0 0 
+    Tuple #1 : 4 3 0 0 
+    Tuple #2 : 6 5 0 0 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way (except that component info +is not copied): +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents3 + +\anchor py_mcdataarraydouble_setpartofvalues1 +

setPartOfValues1()

+We create two arrays: +- a "large" (4x4) zero array \b da to assign to and +- a smaller (2x2) array \b dv filled with values [7.,8.,9.,10]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_1 +Now we copy \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_2 +As result contents of the array \b da are as follows. +
+    Info of components :"v1"   "v2"   "v3"   "v4"
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 8 0 
+    Tuple #2 : 0 9 10 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and copy \b dv into a component of \b da. + +Note that the last parameter \b strictCompoCompare should be \c False +in this case, else \ref ParaMEDMEM::DataArrayDouble::setPartOfValues1() +throws an exception because \b da has 2 components but only one target +component is specified. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 8 0 0 
+    Tuple #2 : 0 9 0 0 
+    Tuple #3 : 0 10 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 8 9 10 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_5 +
+    Tuple #0 : 0 7 0 8 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 9 0 10 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_6 + + + +\anchor py_mcdataarraydouble_setpartofvaluessimple1 +

setPartOfValuesSimple1()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_1 +Now we assign \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_6 + + +\anchor py_mcdataarraydouble_setpartofvaluessimple2 +

setPartOfValuesSimple2()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples and component to assign to by a list [1,2]. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple2() can't +be explicitly called in Python. + + +\anchor py_mcdataarraydouble_setpartofvaluessimple3 +

setPartOfValuesSimple3()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples to assign to by a list [1,2]. And we specify +components to assign to using slicing: 1:3. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple3() can't +be explicitly called in Python. + + +\anchor py_mcdataarraydouble_setpartofvalues2 +

setPartOfValues2()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with + indices [0,1,2]. This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2,3] . +This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 7  0  8  9 10 11 12
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues2() can't +be explicitly called in Python. + + +\anchor py_mcdataarraydouble_setpartofvalues3 +

setPartOfValues3()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with +indices [0,1,2] which are specified using slicing: "0:3". +This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2] using \a +slice notation "0:4:2". This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 0  0  0  0  0  0  0   
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues3() can't +be explicitly called in Python. + + +\anchor py_mcdataarrayint_setselectedcomponents +

Set part of values of DataArrayInt

+

setSelectedComponents()

+First, we create a 'source' array. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents1 +Now we create a larger zero array and assign the array \b da to it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents2 +As result contents of the array \b dv are as follows. +
+Info of components : "a2"   "a1"   "v3"   "v4"   
+    Tuple #0 : 2 1 0 0 
+    Tuple #1 : 4 3 0 0 
+    Tuple #2 : 6 5 0 0 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way (except that component info +is not copied): +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents3 + +\anchor py_mcdataarrayint_setpartofvalues1 +

setPartOfValues1()

+We create two arrays: +- a "large" (4x4) zero array \b da to assign to, and +- a smaller (2x2) array \b dv filled with values [7,8,9,10]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_1 +Now we copy \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_2 +As result contents of the array \b da are as follows. +
+    Info of components :"v1"   "v2"   "v3"   "v4"
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 8 0 
+    Tuple #2 : 0 9 10 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and copy \b dv into a component of \b da. + +Note that the last parameter \b strictCompoCompare should be \c False +in this case, else \ref ParaMEDMEM::DataArrayInt::setPartOfValues1() +throws an exception because \b da has 2 components but only one target +component is specified. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 8 0 0 
+    Tuple #2 : 0 9 0 0 
+    Tuple #3 : 0 10 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 8 9 10 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_5 +
+    Tuple #0 : 0 7 0 8 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 9 0 10 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_6 + + + +\anchor py_mcdataarrayint_setpartofvaluessimple1 +

setPartOfValuesSimple1()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_1 +Now we assign \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_6 + + +\anchor py_mcdataarrayint_setpartofvaluessimple2 +

setPartOfValuesSimple2()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples and component to assign to by a list [1,2]. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple2() can't +be explicitly called in Python. + + +\anchor py_mcdataarrayint_setpartofvaluessimple3 +

setPartOfValuesSimple3()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples to assign to by a list [1,2]. And we specify +components to assign to using slicing: 1:3. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple3() can't +be explicitly called in Python. + + +\anchor py_mcdataarrayint_setpartofvalues2 +

setPartOfValues2()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with + indices [0,1,2]. This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2,3] . +This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 7  0  8  9 10 11 12
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues2() can't +be explicitly called in Python. + + +\anchor py_mcdataarrayint_setpartofvalues3 +

setPartOfValues3()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with +indices [0,1,2] which are specified using slicing: "0:3". +This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2] using \a +slice notation "0:4:2". This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 0  0  0  0  0  0  0   
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues3() can't +be explicitly called in Python. + + +\anchor py_mcdataarraydouble_getdifferentvalues +

Excluding coincident tuples from DataArrayDouble

+ +The code below creates an array of real values and than an array of + unique values, not closer one to another than 0.2, is retrieved from it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_getDifferentValues1 + + +\anchor cpp_mcdataarraydouble_findcommontuples +

Finding coincident tuples in DataArrayDouble

+ +Let's create an array of 6 tuples and 2 components that can be + considered as coordinates of 6 points in 2D space. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples1 +Now we find points that are not far each from other than 1e-1. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples2 +As we can realize from the above code, a hardcoded array \b expected3 is equal + to the raw data of a DataArrayInt \b c and a hardcoded array \b expected4 is equal + to the raw data of the DataArrayInt \b cI. + +The array \b c contains indices of 5 coincident points. The array \b + cI shows us boundaries of (cI->getNumberOfTuples()-1) = 2 groups of coincident points: +- The first group starts at index 0 and includes (3 - 0) = 3 points: 0,3,4. +- The second group starts at index 3 and includes (5 - 3) = 2 points: 1,2. + +\anchor cpp_mcdataarraydouble_meldwith +

Concatenating DataArrayDouble's by appending components

+ +In this example we create two data arrays including \b same number of +tuples and then we concatenate them using \ref +ParaMEDMEM::DataArrayDouble::meldWith "meldWith()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_Meld1_1 +Now the array \b da1 includes 7 tuples (as before) of 3 components +each. Its components are: "c0da1","c1da1","c0da2". + + +\anchor cpp_mcdataarrayint_meldwith +

Concatenating DataArrayInt's by appending components

+ +In this example we create two data arrays including \b same number of +tuples and then we concatenate them using \ref +ParaMEDMEM::DataArrayInt::meldWith "meldWith()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_Meld1_1 +Now the array \b da1 includes 7 tuples (as before) of 3 components +each. Its components are: "c0da1","c1da1","c0da2". + + +\anchor py_mcdataarraydouble_KeepSelectedComponents + +

Creation of a sub-part of the DataArrayDouble by selecting components

+ +\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_1 +We created an array \b a1 containing 5 tuples of 4 components each (20 +values). Now we are going to create an array \b a2 containing some +components of \b a1. +\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_2 +Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus +the result array \b a2 includes 30 elements (5 tuples per 6 components). + + +\anchor py_mcdataarrayint_keepselectedcomponents + +

Creation of a sub-part of the DataArrayInt by selecting components

+ +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_1 +We created an array \b a1 containing 5 tuples of 4 components each (20 +values). Now we are going to create an array \b a2 containing some +components of \b a1. +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_2 +Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus +the result array \b a2 includes 30 elements (5 tuples per 6 components). + +Note that +\ref ParaMEDMEM::DataArrayInt::keepSelectedComponents() "DataArrayInt::keepSelectedComponents()" +is called, providing the same result, by the following python code: +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_3 \anchor cpp_mcfielddouble_subpart1 + +

Creation of a sub part of a field


Creation of a sub part of a field on cells

\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_1 -The field on cells \b f1 lies on a mesh containg 5 cells and 9 nodes. +The field on cells \b f1 lies on a mesh containing 5 cells and 9 nodes. So this field \b f1 contains 5 tuples of 2 components each (10 values). Now let's create a subfield on cells \b f2 from \b f1. \snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_2 @@ -26,7 +1850,7 @@ The underlying mesh of \b f2 contains a newly created mesh with 3 cells (not as

Creation of a sub part of a field on nodes

\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_3 -The field on nodes \b f1 lies on a mesh containg 5 cells and 9 nodes. +The field on nodes \b f1 lies on a mesh containing 5 cells and 9 nodes. So this field \b f1 contains 9 tuples of 2 components each (18 values). Now let's create a subfield on nodes \b f2 from \b f1. \snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_4 @@ -84,7 +1908,7 @@ At this level the connectivity part of the mesh \b mesh as been defined. Now let \snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_4 -At this level mesh is usable. When this mesh is no more needed simply call decrRef to decrement its reference counter. +At this level mesh is usable. When this mesh is no more needed simply call decrRef() to decrement its reference counter. \snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_5 @@ -101,7 +1925,7 @@ Firstly retrieve for each direction the discretization and build a \ref ParaMEDM Then create ParaMEDMEM::MEDCouplingCMesh instance giving the 2 instances of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" obtained above. -There are 2 technics to get it. +There are 2 techniques to get it. Either : diff --git a/doc/doxygen/medcouplingexamplescpponly.dox b/doc/doxygen/medcouplingexamplescpponly.dox new file mode 100644 index 000000000..2049312b9 --- /dev/null +++ b/doc/doxygen/medcouplingexamplescpponly.dox @@ -0,0 +1,36 @@ +/*! +\page medcouplingexamplescpponly MEDCoupling C++ examples + +\anchor cpp_mcfielddouble_fillFromAnalytic_c_func +

Filling a field using a C function

+ +We want to create a 3D vector field lying on a 2D mesh using a C function as a value +generator. For that, first, we define the function that computes 3 values basing on 2 +coordinates of a 2D point. +\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0 +Then we create the 2D mesh and the field on it, and finally we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) "fillFromAnalytic()" +to fill the field with values each composed of 3 components. +\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1 +As a result, number of tuples in the field equals to the number of cells in the mesh, +and number of components equals to 3 as required. + + +\anchor cpp_mcfielddouble_applyFunc_c_func +

Changing a field by applying a C function

+ +We want to transform a 2D vector field to a 3D vector field by +applying a C function to each vector value. For that, first, we define the function +that computes 3 values basing on 2 components of a 2D vector. +\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0 +Then we create the 2D mesh and the vector field on it. +\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1 +Finally we use +\ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) "applyFunc()" +to change the field values. +\snippet MEDCouplingExamplesTest.cxx Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2 +As a result, number of tuples in the field equals to the number of cells in the mesh, +and number of components becomes equal to 3 as required. + + +*/ diff --git a/doc/doxygen/static/footer.html b/doc/doxygen/static/footer.html index 4c89a2ba1..f0455f21f 100755 --- a/doc/doxygen/static/footer.html +++ b/doc/doxygen/static/footer.html @@ -3,10 +3,9 @@
- Copyright © 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+ Copyright © 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
- \ No newline at end of file diff --git a/doc/doxygen/static/header.html.in b/doc/doxygen/static/header.html.in index 4571b4363..d434d830d 100755 --- a/doc/doxygen/static/header.html.in +++ b/doc/doxygen/static/header.html.in @@ -5,6 +5,8 @@ $title + + $treeview $search $mathjax diff --git a/doc/salome/CMakeLists.txt b/doc/salome/CMakeLists.txt index ac4647872..9f65c0753 100644 --- a/doc/salome/CMakeLists.txt +++ b/doc/salome/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am index 6f578031c..1d506684b 100644 --- a/doc/salome/Makefile.am +++ b/doc/salome/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/tui/CMakeLists.txt b/doc/salome/tui/CMakeLists.txt index 88f84b6c0..c44837992 100644 --- a/doc/salome/tui/CMakeLists.txt +++ b/doc/salome/tui/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/tui/Makefile.am b/doc/salome/tui/Makefile.am index 7a3c472c1..6cf42db2d 100644 --- a/doc/salome/tui/Makefile.am +++ b/doc/salome/tui/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in index ba7a2ca9b..ea4f73cdb 100755 --- a/doc/salome/tui/doxyfile.in +++ b/doc/salome/tui/doxyfile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2013 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 diff --git a/doc/salome/tui/static/footer.html b/doc/salome/tui/static/footer.html index 5b030c021..5a56e23a2 100755 --- a/doc/salome/tui/static/footer.html +++ b/doc/salome/tui/static/footer.html @@ -6,7 +6,7 @@
-Copyright © 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+Copyright © 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/idl/CMakeLists.txt b/idl/CMakeLists.txt index 3556b4e15..de987362b 100644 --- a/idl/CMakeLists.txt +++ b/idl/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ # # Author : Anthony Geay (CEA/DEN) -INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/UseOMNIORB.cmake) +INCLUDE(${KERNEL_ROOT_DIR}/salome_adm/cmake_files/deprecated/UseOMNIORB.cmake) INCLUDE_DIRECTORIES( ${OMNIORB_INCLUDE_DIRS} diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index da69cb4a0..df326a56f 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -205,6 +205,8 @@ SET(MED_RESOURCES_FILES test_2D.sauve allPillesTest.sauv BDC-714.sauv + portico_3subs.sauv + agitateur.med ) IF(MED_ENABLE_GUI) diff --git a/resources/agitateur.med b/resources/agitateur.med new file mode 100644 index 000000000..10529512c Binary files /dev/null and b/resources/agitateur.med differ diff --git a/resources/portico_3subs.sauv b/resources/portico_3subs.sauv new file mode 100644 index 000000000..d672a118f --- /dev/null +++ b/resources/portico_3subs.sauv @@ -0,0 +1,182 @@ + ENREGISTREMENT DE TYPE 4 + NIVEAU 18 NIVEAU ERREUR 0 DIMENSION 3 + DENSITE 0.00000E+00 + ENREGISTREMENT DE TYPE 7 + NOMBRE INFO CASTEM2000 8 + IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1 + NSDPGE 0 + ENREGISTREMENT DE TYPE 2 + PILE NUMERO 1NBRE OBJETS NOMMES 6NBRE OBJETS 6 + PBAS POT1 POT2 POUTL STOT EL1 + 4 1 2 3 5 6 + 2 0 0 2 2 + 0 0 + 1 2 2 3 + 2 0 0 2 3 + 0 0 0 + 4 5 5 6 6 7 + 2 0 0 2 1 + 0 + 3 7 + 1 0 0 1 2 + 0 0 + 1 4 + 2 0 0 2 6 + 0 0 0 0 0 0 + 1 2 2 3 4 5 5 6 6 7 + 3 7 + 1 0 0 1 7 + 0 0 0 0 0 0 0 + 1 2 4 5 6 3 7 + ENREGISTREMENT DE TYPE 2 + PILE NUMERO 32NBRE OBJETS NOMMES 4NBRE OBJETS 7 + 0P0 0P1 1P0 1P1 + 1 4 3 7 + 7 + 1 2 6 3 4 5 7 + ENREGISTREMENT DE TYPE 2 + PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1 + 96 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 5.00000000000000E-01 5.00000000000000E-01 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 3.33333333333333E-01 + 3.33333333333333E-01 1.00000000000000E+00 0.00000000000000E+00 + 6.66666666666667E-01 3.33333333333333E-01 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 3.00000000000000E+03 -2.00000000000000E+04 + 6.00000000000000E+03 0.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 -1.00000000000000E+03 + -1.00000000000000E+03 1.00000000000000E+03 0.00000000000000E+00 + ENREGISTREMENT DE TYPE 2 + PILE NUMERO 39NBRE OBJETS NOMMES 1NBRE OBJETS 1 + CHAM1D + 1 + 3 2 6 11 + CONTRAINTES + -1 27665 6 0 0 0 -1 0 5 -2 + 27882 6 0 0 0 -2 0 5 -3 27931 + 6 0 0 0 -3 0 5 + 19363 19664 19888 + + 27833 27840 27847 27854 27861 27868 + EFFX EFFY EFFZ MOMX MOMY MOMZ + REAL*8 REAL*8 REAL*8 REAL*8 + REAL*8 REAL*8 + 2 2 0 0 + -7.68749999999959E-03 -7.68749999999959E-03 -4.56249999999959E-03 + -4.56249999999959E-03 + 2 2 0 0 + -6.11141334691317E-07 -6.11141334691317E-07 -6.11141334690612E-07 + -6.11141334690612E-07 + 2 2 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 + 2 2 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 + 2 2 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 + 2 2 0 0 + 1.32422443924838E-04 1.32728014592183E-04 1.32728014592184E-04 + 1.33033585259529E-04 + 27826 27903 27889 27917 27910 27896 + EFFX EFFY EFFZ MOMX MOMY MOMZ + REAL*8 REAL*8 REAL*8 REAL*8 + REAL*8 REAL*8 + 2 3 0 0 + -8.20833333333293E-03 -8.20833333333293E-03 -6.12499999999960E-03 + -6.12499999999960E-03 -4.04166666666627E-03 -4.04166666666627E-03 + 2 3 0 0 + 6.11141334689149E-07 6.11141334689149E-07 6.11141334689393E-07 + 6.11141334689393E-07 6.11141334688905E-07 6.11141334688905E-07 + 2 3 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 2 3 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 2 3 0 0 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 2 3 0 0 + -1.32422443922787E-04 -1.32626157701017E-04 -1.32626157701017E-04 + -1.32829871479247E-04 -1.32829871479247E-04 -1.33033585257476E-04 + 27651 27952 27938 27966 27959 27945 + EFFX EFFY EFFZ MOMX MOMY MOMZ + REAL*8 REAL*8 REAL*8 REAL*8 + REAL*8 REAL*8 + 2 1 0 0 + -6.11141334691013E-07 -6.11141334691013E-07 + 2 1 0 0 + 0.00000000000000E+00 0.00000000000000E+00 + 2 1 0 0 + -5.81088996365331E-15 -5.81088996365331E-15 + 2 1 0 0 + 0.00000000000000E+00 0.00000000000000E+00 + 2 1 0 0 + -3.66966414738893E-04 -3.66966414744704E-04 + 2 1 0 0 + 0.00000000000000E+00 0.00000000000000E+00 + ENREGISTREMENT DE TYPE 2 + PILE NUMERO 40NBRE OBJETS NOMMES 0NBRE OBJETS 3 + 2 2 + 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 + 2 2 + 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 + 2 2 + 1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 -5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 1.00000000000000E+00 0.00000000000000E+00 5.00000000000000E-01 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 1.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 0.00000000000000E+00 + -5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 0.00000000000000E+00 1.00000000000000E+00 + 5.00000000000000E-01 0.00000000000000E+00 0.00000000000000E+00 + 0.00000000000000E+00 1.00000000000000E+00 + ENREGISTREMENT DE TYPE 5 +LABEL_AUTOMATIQUE_2 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d9ebfc851..514a317a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -52,15 +52,19 @@ IF(MPI_IS_OK) ENDIF(MPI_IS_OK) IF(MED_ENABLE_SPLITTER) - SET(COMMON_SUBDIRS ${COMMON_SUBDIRS} MEDPartitioner) - SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} MEDSPLITTER) - IF(SWIG_STATUS) - SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} MEDSPLITTER_Swig) - ENDIF(SWIG_STATUS) + IF(MED_ENABLE_MED3) + SET(COMMON_SUBDIRS ${COMMON_SUBDIRS} MEDPartitioner) + SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} MEDSPLITTER) + IF(SWIG_STATUS) + SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} MEDSPLITTER_Swig) + ENDIF(SWIG_STATUS) + ENDIF(MED_ENABLE_MED3) ENDIF(MED_ENABLE_SPLITTER) IF(MED_ENABLE_RENUMBER) - SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} RENUMBER) + IF(MED_ENABLE_MED3) + SET(OLD_COMMON_SUBDIRS ${OLD_COMMON_SUBDIRS} RENUMBER) + ENDIF(MED_ENABLE_MED3) ENDIF(MED_ENABLE_RENUMBER) IF(MED_ENABLE_KERNEL) diff --git a/src/INTERP_KERNEL/BBTree.txx b/src/INTERP_KERNEL/BBTree.txx index 7b3d03782..f977e24e3 100644 --- a/src/INTERP_KERNEL/BBTree.txx +++ b/src/INTERP_KERNEL/BBTree.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -52,7 +52,9 @@ public: \param elems array to the indices of the elements contained in the BBTree \param level level in the BBTree recursive structure \param nbelems nb of elements in the BBTree - \param epsilon precision to which points are decided to be coincident + \param epsilon precision to which points are decided to be coincident. Epsilon can be positive or negative. + If \a epsilon is positive the request method will enlarge the computed bounding box (more matching elems return). + If negative the given bounding box will be tighten (less matching elems return). Parameters \a elems and \a level are used only by BBTree itself for creating trees recursively. A typical use is therefore : \code @@ -64,7 +66,7 @@ public: \endcode */ - BBTree(const double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1E-12): + BBTree(const double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1e-12): _left(0), _right(0), _level(level), _bb(bbs), _terminal(false),_nbelems(nbelems),_epsilon(epsilon) { if (nbelems < MIN_NB_ELEMS || level> MAX_LEVEL) diff --git a/src/INTERP_KERNEL/BBTreeDst.txx b/src/INTERP_KERNEL/BBTreeDst.txx new file mode 100644 index 000000000..b7c83ad72 --- /dev/null +++ b/src/INTERP_KERNEL/BBTreeDst.txx @@ -0,0 +1,217 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#ifndef __BBTREEDST_TXX__ +#define __BBTREEDST_TXX__ + +#include +#include + +#include +#include +#include + +template +class BBTreeDst +{ +private: + BBTreeDst* _left; + BBTreeDst* _right; + int _level; + double _max_left; + double _min_right; + const double *_bb; + std::vector _elems; + double *_terminal; + int _nbelems; + + static const int MIN_NB_ELEMS=15; + static const int MAX_LEVEL=20; +public: + BBTreeDst(const double* bbs, int* elems, int level, int nbelems): + _left(0),_right(0),_level(level),_bb(bbs),_terminal(0),_nbelems(nbelems) + { + if((nbelems < MIN_NB_ELEMS || level> MAX_LEVEL)) + _terminal=new double[2*dim]; + _elems.resize(nbelems); + for (int i=0; i(nodes, nodes+nbelems/2, nodes+nbelems); + double median = *(nodes+nbelems/2); + delete [] nodes; + std::vector new_elems_left; + std::vector new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits::max(); + double min_right= std::numeric_limits::max(); + for(int i=0; imedian) + { + new_elems_right.push_back(elem); + if (minmax_left) max_left = max; + } + } + _max_left=max_left; + _min_right=min_right; + int *tmp; + tmp=0; + if(!new_elems_left.empty()) + tmp=&(new_elems_left[0]); + _left=new BBTreeDst(bbs, tmp, level+1, (int)new_elems_left.size()); + tmp=0; + if(!new_elems_right.empty()) + tmp=&(new_elems_right[0]); + _right=new BBTreeDst(bbs, tmp, level+1, (int)new_elems_right.size()); + } + + ~BBTreeDst() + { + delete _left; + delete _right; + delete [] _terminal; + } + + void getElemsWhoseMinDistanceToPtSmallerThan(const double *pt, double minOfMaxDstsSq, std::vector& elems) const + { + if(_terminal) + { + for(int i=0; i<_nbelems; i++) + { + if(GetMinDistanceFromBBoxToPt(_bb+_elems[i]*2*dim,pt)minOfMaxDsts) + { _left->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); return ; } + if(pt[_level%dim]-_max_left>minOfMaxDsts) + { _right->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); return ; } + _left->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); + _right->getElemsWhoseMinDistanceToPtSmallerThan(pt,minOfMaxDstsSq,elems); + } + } + + void getMinDistanceOfMax(const double *pt, double& minOfMaxDstsSq) const + { + if(_terminal) + { + if(GetMinDistanceFromBBoxToPt(_terminal,pt)>minOfMaxDstsSq)//min it is not a bug + return ; + for(int i=0; i<_nbelems; i++) + { + minOfMaxDstsSq=std::min(minOfMaxDstsSq,GetMaxDistanceFromBBoxToPt(_bb+_elems[i]*2*dim,pt)); + } + } + else + { + double minOfMaxDsts=sqrt(minOfMaxDstsSq); + if(_min_right-pt[_level%dim]>minOfMaxDsts) + { _left->getMinDistanceOfMax(pt,minOfMaxDstsSq); return ; } + if(pt[_level%dim]-_max_left>minOfMaxDsts) + { _right->getMinDistanceOfMax(pt,minOfMaxDstsSq); return ; } + _left->getMinDistanceOfMax(pt,minOfMaxDstsSq); + _right->getMinDistanceOfMax(pt,minOfMaxDstsSq); + } + } + + void fillBBoxTerminal(const double* bbs) + { + for(int j=0;j::max(); + _terminal[2*j+1]=-std::numeric_limits::max(); + } + for(int i=0;i<_nbelems;i++) + { + for(int j=0;jmax -> no cells in this + return std::numeric_limits::max(); + + } + + static double GetMinDistanceFromBBoxToPt(const double *bbox, const double *pt) + { + if(bbox[0]<=bbox[1]) + { + double zeRes=0.; + for (int idim=0; idimmax -> no cells in this + return std::numeric_limits::max(); + } +}; + +#endif diff --git a/src/INTERP_KERNEL/BBTreePts.txx b/src/INTERP_KERNEL/BBTreePts.txx new file mode 100644 index 000000000..17d0c7f32 --- /dev/null +++ b/src/INTERP_KERNEL/BBTreePts.txx @@ -0,0 +1,222 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef __BBTREEPTS_TXX__ +#define __BBTREEPTS_TXX__ + +#include +#include + +#include +#include +#include + +template +class BBTreePts +{ + +private: + BBTreePts* _left; + BBTreePts* _right; + int _level; + double _max_left; + double _min_right; + const double *_pts; + typename std::vector _elems; + bool _terminal; + ConnType _nbelems; + double _epsilon; + + static const int MIN_NB_ELEMS=15; + static const int MAX_LEVEL=20; +public: + + /*! + Constructor of the bounding box tree + \param [in] pts pointer to the array containing the points that are to be indexed. + \param [in] elems array to the indices of the elements contained in the BBTreePts + \param [in] level level in the BBTreePts recursive structure + \param [in] nbelems nb of elements in the BBTreePts + \param [in] epsilon precision to which points are decided to be coincident. Contrary to BBTree, the absolute epsilon is computed. So the internal epsilon is always positive. + + Parameters \a elems and \a level are used only by BBTreePts itself for creating trees recursively. A typical use is therefore : + \code + int nbelems=... + double* pts= new double[dim*nbelems]; + // filling pts ... + ... + BBTreePts<2> tree = new BBTreePts<2>(elems,0,0,nbelems,1e-12); + \endcode + */ + BBTreePts(const double *pts, const ConnType *elems, int level, ConnType nbelems, double epsilon=1e-12): + _left(0),_right(0),_level(level),_pts(pts),_terminal(nbelems < MIN_NB_ELEMS || level> MAX_LEVEL),_nbelems(nbelems),_epsilon(std::abs(epsilon)) + { + double *nodes=new double[nbelems]; + _elems.resize(nbelems); + for (ConnType i=0;i(nodes, nodes+nbelems/2, nodes+nbelems); + double median=*(nodes+nbelems/2); + delete [] nodes; + std::vector new_elems_left,new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits::max(); + double min_right= std::numeric_limits::max(); + for(int i=0;imedian) + { + new_elems_right.push_back(elem); + if(mxmax_left) max_left=mx; + } + } + _max_left=max_left+_epsilon; + _min_right=min_right-_epsilon; + ConnType *tmp; + tmp=0; + if(!new_elems_left.empty()) + tmp=&(new_elems_left[0]); + _left=new BBTreePts(pts, tmp, level+1, (int)new_elems_left.size(),_epsilon); + tmp=0; + if(!new_elems_right.empty()) + tmp=&(new_elems_right[0]); + _right=new BBTreePts(pts, tmp, level+1, (int)new_elems_right.size(),_epsilon); + } + + + + ~BBTreePts() + { + delete _left; + delete _right; + } + + /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx + Contrary to BBTreePts::getElementsAroundPoint the norm 2 is used here. + + \param [in] xx pointer to query point coords + \param [in] threshold + \param elems list of elements (given in 0-indexing) intersecting the bounding box + \sa BBTreePts::getElementsAroundPoint + */ + double getElementsAroundPoint2(const double *xx, double threshold, ConnType& elem) const + { + // terminal node : return list of elements intersecting bb + if(_terminal) + { + double ret=std::numeric_limits::max(); + for(ConnType i=0;i<_nbelems;i++) + { + const double* const bb_ptr=_pts+_elems[i]*dim; + double tmp=0.; + for(int idim=0;idimgetElementsAroundPoint2(xx,threshold,elem); + if(xx[_level%dim]-s>_max_left) + return _right->getElementsAroundPoint2(xx,threshold,elem); + int eleml,elemr; + double retl=_left->getElementsAroundPoint2(xx,threshold,eleml); + double retr=_right->getElementsAroundPoint2(xx,threshold,elemr); + if(retl& elems) const + { + // terminal node : return list of elements intersecting bb + if(_terminal) + { + for(ConnType i=0;i<_nbelems;i++) + { + const double* const bb_ptr=_pts+_elems[i]*dim; + bool intersects = true; + for(int idim=0;idimgetElementsAroundPoint(xx,elems); + return; + } + if(xx[_level%dim]>_max_left) + { + _right->getElementsAroundPoint(xx,elems); + return; + } + _left->getElementsAroundPoint(xx,elems); + _right->getElementsAroundPoint(xx,elems); + } + + int size() const + { + if(_terminal) + return _nbelems; + return _left->size()+_right->size(); + } +}; + +#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx b/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx index 27eeb5e37..e49b4df14 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,25 @@ namespace INTERP_KERNEL private: T *_ptr; }; + + template + class AutoCPtr + { + public: + AutoCPtr(T *ptr=0):_ptr(ptr) { } + ~AutoCPtr() { destroyPtr(); } + AutoCPtr &operator=(T *ptr) { destroyPtr(); _ptr=ptr; return *this; } + T *operator->() { return _ptr ; } + const T *operator->() const { return _ptr; } + T& operator*() { return *_ptr; } + const T& operator*() const { return *_ptr; } + operator T *() { return _ptr; } + operator const T *() const { return _ptr; } + private: + void destroyPtr() { free(_ptr); } + private: + T *_ptr; + }; } #endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelException.cxx b/src/INTERP_KERNEL/Bases/InterpKernelException.cxx index 9f777b61f..2efd8d1df 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelException.cxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelException.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Bases/InterpKernelException.hxx b/src/INTERP_KERNEL/Bases/InterpKernelException.hxx index 3b573c024..ae63b39b0 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelException.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelException.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx index 0fd4102a9..6d7313a9b 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx @@ -1,10 +1,21 @@ -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. +// Copyright (C) 2001-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx index e4fc93c81..0675d577e 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx @@ -1,10 +1,21 @@ -// Copyright (C) 2001, 2002, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. +// Copyright (C) 2001-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx index 472891549..f8b21d826 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx @@ -1,11 +1,21 @@ -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -// Free Software Foundation, Inc. +// Copyright (C) 2001-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx b/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx index b946364b8..d78e42d92 100644 --- a/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx +++ b/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx index 3d43cb6d5..58afa368e 100644 --- a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx +++ b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -61,6 +61,12 @@ namespace INTERP_KERNEL NORM_MAXTYPE = 33 } NormalizedCellType; + /// Type describing the different ways in which the hexahedron can be split into tetrahedra. + /// The PLANAR_* policies persume that each face is to be considered planar, while the general + /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra + /// that result from the split. + typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; + class GenericMesh {}; } diff --git a/src/INTERP_KERNEL/BoundingBox.cxx b/src/INTERP_KERNEL/BoundingBox.cxx index 5a1114394..c6a0c0d5d 100644 --- a/src/INTERP_KERNEL/BoundingBox.cxx +++ b/src/INTERP_KERNEL/BoundingBox.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/BoundingBox.hxx b/src/INTERP_KERNEL/BoundingBox.hxx index ab5f5bbfe..7fd7d80a0 100644 --- a/src/INTERP_KERNEL/BoundingBox.hxx +++ b/src/INTERP_KERNEL/BoundingBox.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CMakeLists.txt b/src/INTERP_KERNEL/CMakeLists.txt index 02d8637bd..f37a2d1b6 100644 --- a/src/INTERP_KERNEL/CMakeLists.txt +++ b/src/INTERP_KERNEL/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,7 @@ SET(interpkernel_SOURCES InterpKernelMeshQuality.cxx InterpKernelCellSimplify.cxx InterpKernelMatrixTools.cxx + VolSurfUser.cxx Bases/InterpKernelException.cxx Geometric2D/InterpKernelGeo2DAbstractEdge.cxx Geometric2D/InterpKernelGeo2DBounds.cxx @@ -78,3 +79,7 @@ INSTALL(TARGETS interpkernel DESTINATION ${MED_salomelib_LIBS}) FILE(GLOB_RECURSE interpkernel_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") FILE(GLOB_RECURSE interpkernel_HEADERS_TXX "${CMAKE_CURRENT_SOURCE_DIR}/*.txx") INSTALL(FILES ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX} DESTINATION ${MED_salomeinclude_HEADERS}) + +# Will be used for SWIG dependencies: +SET (interpkernel_HEADERS_HXX PARENT_SCOPE) +SET (interpkernel_HEADERS_TXX PARENT_SCOPE) diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx index 6a027a819..853e99e24 100644 --- a/src/INTERP_KERNEL/CellModel.cxx +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -113,8 +113,11 @@ namespace INTERP_KERNEL _quadratic=false; _dyn=false; _extruded_type=NORM_ERROR; + _reverse_extruded_type=NORM_ERROR; _linear_type=NORM_ERROR; _quadratic_type=NORM_ERROR; + _quadratic_type2=NORM_ERROR; + _nb_of_little_sons=std::numeric_limits::max(); switch(type) { case NORM_POINT1: @@ -124,7 +127,7 @@ namespace INTERP_KERNEL break; case NORM_SEG2: { - _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _is_simplex=true; _is_extruded=true; + _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _quadratic_type2=NORM_SEG3; _is_simplex=true; _is_extruded=true; _reverse_extruded_type=NORM_POINT1; _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_con[0][0]=0; _nb_of_sons_con[0]=1; _sons_con[1][0]=1; _nb_of_sons_con[1]=1; @@ -157,11 +160,17 @@ namespace INTERP_KERNEL _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _nb_of_sons_con[3]=3; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=6; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; + _little_sons_con[3][0]=0; _little_sons_con[3][1]=3; + _little_sons_con[4][0]=1; _little_sons_con[4][1]=3; + _little_sons_con[5][0]=2; _little_sons_con[5][1]=3; } break; case NORM_HEXA8: { - _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _is_simplex=false; _is_extruded=true; + _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _quadratic_type2=NORM_HEXA27; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_QUAD4; _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4; @@ -169,11 +178,23 @@ namespace INTERP_KERNEL _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _nb_of_sons_con[5]=4; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=12; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; + _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; + _little_sons_con[5][0]=5; _little_sons_con[5][1]=6; + _little_sons_con[6][0]=6; _little_sons_con[6][1]=7; + _little_sons_con[7][0]=7; _little_sons_con[7][1]=4; + _little_sons_con[8][0]=0; _little_sons_con[8][1]=4; + _little_sons_con[9][0]=1; _little_sons_con[9][1]=5; + _little_sons_con[10][0]=2; _little_sons_con[10][1]=6; + _little_sons_con[11][0]=3; _little_sons_con[11][1]=7; } break; case NORM_QUAD4: { - _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _is_simplex=false; _is_extruded=true; + _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _quadratic_type2=NORM_QUAD9; _is_simplex=false; _is_extruded=true; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -183,7 +204,7 @@ namespace INTERP_KERNEL break; case NORM_TRI3: { - _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _is_simplex=true; + _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _quadratic_type2=NORM_TRI7; _is_simplex=true; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -237,17 +258,34 @@ namespace INTERP_KERNEL _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _nb_of_sons_con[3]=3; _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _nb_of_sons_con[4]=3; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=8; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; + _little_sons_con[4][0]=0; _little_sons_con[4][1]=4; + _little_sons_con[5][0]=1; _little_sons_con[5][1]=4; + _little_sons_con[6][0]=2; _little_sons_con[6][1]=4; + _little_sons_con[7][0]=3; _little_sons_con[7][1]=4; } break; case NORM_PENTA6: { - _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15; _is_simplex=false; _is_extruded=true; + _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_TRI3; _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; _sons_con[4][0]=2; _sons_con[4][1]=5; _sons_con[4][2]=3; _sons_con[4][3]=0; _nb_of_sons_con[4]=4; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _nb_of_little_sons=9; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; + _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; + _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; + _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; + _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; + _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; } break; case NORM_TETRA10: @@ -258,6 +296,12 @@ namespace INTERP_KERNEL _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6; _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _sons_con[2][3]=8; _sons_con[2][4]=9; _sons_con[2][5]=5; _nb_of_sons_con[2]=6; _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _sons_con[3][3]=9; _sons_con[3][4]=7; _sons_con[3][5]=6; _nb_of_sons_con[3]=6; _quadratic=true; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=4; _nb_of_little_sons=6; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=5; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=6; + _little_sons_con[3][0]=0; _little_sons_con[3][1]=3; _little_sons_con[3][2]=7; + _little_sons_con[4][0]=1; _little_sons_con[4][1]=3; _little_sons_con[4][2]=8; + _little_sons_con[5][0]=2; _little_sons_con[5][1]=3; _little_sons_con[5][2]=9; } break; case NORM_HEXGP12: @@ -284,6 +328,14 @@ namespace INTERP_KERNEL _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _sons_con[2][3]=10; _sons_con[2][4]=11; _sons_con[2][5]=6; _nb_of_sons_con[2]=6; _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _sons_con[3][3]=11; _sons_con[3][4]=12; _sons_con[3][5]=7; _nb_of_sons_con[3]=6; _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _sons_con[4][3]=12; _sons_con[4][4]=9; _sons_con[4][5]=8; _nb_of_sons_con[4]=6; _quadratic=true; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=5; _nb_of_little_sons=8; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=6; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=7; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=8; + _little_sons_con[4][0]=0; _little_sons_con[4][1]=4; _little_sons_con[4][2]=9; + _little_sons_con[5][0]=1; _little_sons_con[5][1]=4; _little_sons_con[5][2]=10; + _little_sons_con[6][0]=2; _little_sons_con[6][1]=4; _little_sons_con[6][2]=11; + _little_sons_con[7][0]=3; _little_sons_con[7][1]=4; _little_sons_con[7][2]=12; } break; case NORM_PENTA15: @@ -295,6 +347,15 @@ namespace INTERP_KERNEL _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _nb_of_sons_con[2]=8; _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _nb_of_sons_con[3]=8; _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _nb_of_sons_con[4]=8; _quadratic=true; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6; _nb_of_little_sons=9; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9; + _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=10; + _little_sons_con[5][0]=5; _little_sons_con[5][1]=3; _little_sons_con[5][2]=11; + _little_sons_con[6][0]=0; _little_sons_con[6][1]=3; _little_sons_con[6][2]=12; + _little_sons_con[7][0]=1; _little_sons_con[7][1]=4; _little_sons_con[7][2]=13; + _little_sons_con[8][0]=2; _little_sons_con[8][1]=5; _little_sons_con[8][2]=14; } break; case NORM_HEXA20: @@ -304,9 +365,21 @@ namespace INTERP_KERNEL _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8; _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _nb_of_sons_con[2]=8; - _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8; - _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8; - _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true; + _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8; + _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8; + _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=8; _nb_of_little_sons=12; + _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=9; + _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=10; + _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=11; + _little_sons_con[4][0]=4; _little_sons_con[4][1]=5; _little_sons_con[4][2]=12; + _little_sons_con[5][0]=5; _little_sons_con[5][1]=6; _little_sons_con[5][2]=13; + _little_sons_con[6][0]=6; _little_sons_con[6][1]=7; _little_sons_con[6][2]=14; + _little_sons_con[7][0]=7; _little_sons_con[7][1]=4; _little_sons_con[7][2]=15; + _little_sons_con[8][0]=0; _little_sons_con[8][1]=4; _little_sons_con[8][2]=16; + _little_sons_con[9][0]=1; _little_sons_con[9][1]=5; _little_sons_con[9][2]=17; + _little_sons_con[10][0]=2; _little_sons_con[10][1]=6; _little_sons_con[10][2]=18; + _little_sons_con[11][0]=3; _little_sons_con[11][1]=7; _little_sons_con[11][2]=19; } break; case NORM_HEXA27: @@ -316,15 +389,15 @@ namespace INTERP_KERNEL _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _sons_con[0][8]=20; _nb_of_sons_con[0]=9; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _sons_con[1][8]=25; _nb_of_sons_con[1]=9; _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _sons_con[2][8]=21; _nb_of_sons_con[2]=9; - _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9; _sons_con[3][8]=22; _nb_of_sons_con[3]=9; - _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _sons_con[4][8]=23; _nb_of_sons_con[4]=9; - _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _sons_con[5][8]=24; _nb_of_sons_con[5]=9; + _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9; _sons_con[3][8]=22; _nb_of_sons_con[3]=9; + _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _sons_con[4][8]=23; _nb_of_sons_con[4]=9; + _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _sons_con[5][8]=24; _nb_of_sons_con[5]=9; _quadratic=true; } break; case NORM_POLYGON: { - _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false; + _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _extruded_type=NORM_POLYHED; _is_simplex=false; _quadratic_type=NORM_QPOLYG; } break; case NORM_POLYHED: @@ -334,7 +407,7 @@ namespace INTERP_KERNEL break; case NORM_QPOLYG: { - _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true; + _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; _is_simplex=false; _quadratic=true; _linear_type=NORM_POLYGON; } break; case NORM_POLYL: @@ -369,6 +442,44 @@ namespace INTERP_KERNEL return std::count(conn,conn+lgth,-1)+1; } + unsigned CellModel::getNumberOfEdgesIn3D(const int *conn, int lgth) const + { + if(!isDynamic()) + return _nb_of_little_sons; + else//polyhedron + return (lgth-std::count(conn,conn+lgth,-1))/2; + } + + NormalizedCellType CellModel::getCorrespondingPolyType() const + { + switch(getDimension()) + { + case 0: + return NORM_POINT1; + case 1: + { + if(!isQuadratic()) + return NORM_POLYL; + throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 1D !"); + } + case 2: + { + if(!isQuadratic()) + return NORM_POLYGON; + else + return NORM_QPOLYG; + } + case 3: + { + if(!isQuadratic()) + return NORM_POLYHED; + throw INTERP_KERNEL::Exception("CellModel::getPolyType : no poly type for quadratic 3D !"); + } + default: + throw INTERP_KERNEL::Exception("CellModel::getPolyType : only dimension 0, 1, 2, 3 are supported !"); + } + } + /*! * Equivalent to getSonType except that this method deals with dynamic type. */ @@ -440,6 +551,44 @@ namespace INTERP_KERNEL throw INTERP_KERNEL::Exception("CellModel::fillSonCellNodalConnectivity2 : no sons on NORM_POLYL !"); } } + + /*! + * Equivalent to CellModel::fillSonCellNodalConnectivity2 except for HEXA8 where the order of sub faces is not has MED file numbering for transformation HEXA8->HEXA27 + */ + unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + { + if(_type==NORM_HEXA8) + { + static const int permutation[6]={0,2,3,4,5,1}; + return fillSonCellNodalConnectivity2(permutation[sonId],nodalConn,lgth,sonNodalConn,typeOfSon); + } + else + return fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); + } + + unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + { + if(!isDynamic()) + { + if(!isQuadratic()) + { + typeOfSon=NORM_SEG2; + sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; + sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; + return 2; + } + else + { + typeOfSon=NORM_SEG3; + sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; + sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; + sonNodalConn[2]=nodalConn[_little_sons_con[sonId][2]]; + return 3; + } + } + else + throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !"); + } //================================================================================ /*! diff --git a/src/INTERP_KERNEL/CellModel.hxx b/src/INTERP_KERNEL/CellModel.hxx index 27ec69f05..d154a2d20 100644 --- a/src/INTERP_KERNEL/CellModel.hxx +++ b/src/INTERP_KERNEL/CellModel.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,7 @@ namespace INTERP_KERNEL public: static const unsigned MAX_NB_OF_SONS=8; static const unsigned MAX_NB_OF_NODES_PER_ELEM=30; + static const unsigned MAX_NB_OF_LITTLE_SONS=12; private: CellModel(NormalizedCellType type); static void buildUniqueInstance(); @@ -55,15 +56,21 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT unsigned getNumberOfNodes() const { return _nb_of_pts; } INTERPKERNEL_EXPORT unsigned getNumberOfSons() const { return _nb_of_sons; } INTERPKERNEL_EXPORT unsigned getNumberOfSons2(const int *conn, int lgth) const; + INTERPKERNEL_EXPORT unsigned getNumberOfEdgesIn3D(const int *conn, int lgth) const; INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; } INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const; INTERPKERNEL_EXPORT NormalizedCellType getExtrudedType() const { return _extruded_type; } + INTERPKERNEL_EXPORT NormalizedCellType getCorrespondingPolyType() const; + INTERPKERNEL_EXPORT NormalizedCellType getReverseExtrudedType() const { return _reverse_extruded_type; } INTERPKERNEL_EXPORT NormalizedCellType getLinearType() const { return _linear_type; } INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType() const { return _quadratic_type; } + INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType2() const { return _quadratic_type2; } INTERPKERNEL_EXPORT NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; } INTERPKERNEL_EXPORT NormalizedCellType getSonType2(unsigned sonId) const; INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const; INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; + INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; + INTERPKERNEL_EXPORT unsigned fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; private: bool _dyn; bool _quadratic; @@ -72,11 +79,15 @@ namespace INTERP_KERNEL unsigned _dim; unsigned _nb_of_pts; unsigned _nb_of_sons; + unsigned _nb_of_little_sons; NormalizedCellType _type; NormalizedCellType _extruded_type; + NormalizedCellType _reverse_extruded_type; NormalizedCellType _linear_type; NormalizedCellType _quadratic_type; + NormalizedCellType _quadratic_type2; unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM]; + unsigned _little_sons_con[MAX_NB_OF_LITTLE_SONS][3]; unsigned _nb_of_sons_con[MAX_NB_OF_SONS]; NormalizedCellType _sons_type[MAX_NB_OF_SONS]; static std::map _map_of_unique_instance; diff --git a/src/INTERP_KERNEL/ConvexIntersector.hxx b/src/INTERP_KERNEL/ConvexIntersector.hxx index 12fe453b9..3b12cdf8b 100644 --- a/src/INTERP_KERNEL/ConvexIntersector.hxx +++ b/src/INTERP_KERNEL/ConvexIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ConvexIntersector.txx b/src/INTERP_KERNEL/ConvexIntersector.txx index a30c6a932..817677b60 100644 --- a/src/INTERP_KERNEL/ConvexIntersector.txx +++ b/src/INTERP_KERNEL/ConvexIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersector.hxx b/src/INTERP_KERNEL/CurveIntersector.hxx index 6a9ee27d5..39ec4f225 100644 --- a/src/INTERP_KERNEL/CurveIntersector.hxx +++ b/src/INTERP_KERNEL/CurveIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersector.txx b/src/INTERP_KERNEL/CurveIntersector.txx index 3281d9929..f6f98485c 100644 --- a/src/INTERP_KERNEL/CurveIntersector.txx +++ b/src/INTERP_KERNEL/CurveIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx b/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx index 26c58420c..df8313442 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P0.txx b/src/INTERP_KERNEL/CurveIntersectorP0P0.txx index d82f4eb58..dd9739e42 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx b/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx index fb42bf140..aefea7d32 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx +++ b/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx b/src/INTERP_KERNEL/CurveIntersectorP0P1.txx index ff43da455..1428b0763 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP0P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx b/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx index ba548b9e3..a61e96e06 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx b/src/INTERP_KERNEL/CurveIntersectorP1P0.txx index 45c1eeb87..1511a4621 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx b/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx index 537fe9714..9998ded39 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx b/src/INTERP_KERNEL/CurveIntersectorP1P1.txx index 1d3b93d73..4c803d07a 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.cxx b/src/INTERP_KERNEL/DirectedBoundingBox.cxx index 60912ed37..2bd5e88a1 100644 --- a/src/INTERP_KERNEL/DirectedBoundingBox.cxx +++ b/src/INTERP_KERNEL/DirectedBoundingBox.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.hxx b/src/INTERP_KERNEL/DirectedBoundingBox.hxx index 3224b6675..65f3b1bd0 100644 --- a/src/INTERP_KERNEL/DirectedBoundingBox.hxx +++ b/src/INTERP_KERNEL/DirectedBoundingBox.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx index 695bbc160..92a70e993 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx index 3fa6f73e7..7ae47ac60 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx index a8d02a3b5..c29ceffad 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx index 29c8c0d9c..1e671ad91 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx index 6e4f13e7b..bd5ef1687 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx index b63382683..ef7dab8eb 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx index e7e737cf4..aca6748ea 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx index 688917adf..ff4c9d9ab 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx index 3a24ef6da..20f18b2ec 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx index 36c484b04..3797d1567 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx index 0fa9d7b5a..f5a84b5fd 100644 --- a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx +++ b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx index c045279d2..479d9d08c 100644 --- a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx +++ b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -17,8 +17,8 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __INTERPKERNELGAUSS_HXX__ -#define __INTERPKERNELGAUSS_HXX__ +#ifndef __INTERPKERNELGAUSSCOORDS_HXX__ +#define __INTERPKERNELGAUSSCOORDS_HXX__ #include "INTERPKERNELDefines.hxx" #include "NormalizedUnstructuredMesh.hxx" @@ -157,4 +157,4 @@ namespace INTERP_KERNEL GaussInfoVector _my_gauss_info; }; } -#endif //INTERPKERNELGAUSS +#endif //INTERPKERNELGAUSSCOORDS diff --git a/src/INTERP_KERNEL/GenMathFormulae.hxx b/src/INTERP_KERNEL/GenMathFormulae.hxx index 9b003ce1d..d1b3da2b3 100644 --- a/src/INTERP_KERNEL/GenMathFormulae.hxx +++ b/src/INTERP_KERNEL/GenMathFormulae.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx index c30b1f698..4330991ff 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx index b0c5b4e2b..8d580a936 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx index 8a9902f08..1b56b15ca 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx index 8780aae35..ed3c2f305 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx index 960ce5183..8242278d7 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx index e3bf49f18..9c3cd74ca 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx index 182fb2580..41c4240c2 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -542,6 +542,20 @@ void Edge::getNormalVector(double *vectOutput) const vectOutput[1]=-tmp; } +Edge *Edge::BuildEdgeFrom3Points(const double *start, const double *middle, const double *end) +{ + Node *b(new Node(start[0],start[1])),*m(new Node(middle[0],middle[1])),*e(new Node(end[0],end[1])); + EdgeLin *e1(new EdgeLin(b,m)),*e2(new EdgeLin(m,e)); + SegSegIntersector inters(*e1,*e2); bool colinearity=inters.areColinears(); delete e1; delete e2; + Edge *ret=0; + if(colinearity) + ret=new EdgeLin(b,e); + else + ret=new EdgeArcCircle(b,m,e); + b->decrRef(); m->decrRef(); e->decrRef(); + return ret; +} + Edge *Edge::BuildEdgeFrom(Node *start, Node *end) { return new EdgeLin(start,end); diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx index 36526ab17..d646efc3c 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -225,6 +225,7 @@ namespace INTERP_KERNEL static Edge *BuildEdgeFrom(Node *start, Node *end); template static Edge *BuildEdgeFrom(Node *start, Node *middle, Node *end); + static Edge *BuildEdgeFrom3Points(const double *start, const double *middle, const double *end); virtual void update(Node *m) = 0; //! returns area between this and axe Ox delimited along Ox by _start and _end. virtual double getAreaOfZone() const = 0; diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx index 18502eb6a..a74ab03a8 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx index 5c079b185..8424b40cb 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx index 4faf2d5e4..321cb0ed5 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx index a1150cb96..2c14ff1fc 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx index 915914097..438341f64 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx index dfe1f81d5..6b7e5859c 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx index d8332e7d0..0a5258ed2 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx index dd1e0ab02..ba69360f2 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx index 17b2459e9..0463ecc21 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx index e345cccf7..06d19bc98 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx index 48ebe58e1..b048a65af 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx index c3edf2dc4..f6ff3c579 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx index a8313481f..28a0606b8 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index b0ee4f1c2..50012b966 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,7 @@ #include "NormalizedUnstructuredMesh.hxx" #include +#include #include #include #include @@ -1144,7 +1145,12 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: std::list retPolsUnderContruction; std::list edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end()); std::map > pol1ZipConsumed; - while(!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty()) + std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0; + for(std::list::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++) + nbOfTurn+=(*itMNT)->size(); + maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn; + nbOfTurn=0; + while(nbOfTurn::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();) { @@ -1206,6 +1212,13 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: retPolsUnderContruction.push_back(tmp); pol1Zip.erase(pol1Zip.begin()); } + nbOfTurn++; + } + if(nbOfTurn==maxNbOfTurn) + { + std::ostringstream oss; oss << "Error during reconstruction of residual of cell ! It appears that either source or/and target mesh is/are not conform !"; + oss << " Number of turns is = " << nbOfTurn << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } for(std::list::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++) { @@ -1215,7 +1228,6 @@ void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std:: for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) delete *it6; delete *it1; - it1=retPolsUnderContruction.erase(it1); } } } diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx index 9f154aa22..9993fe8e2 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/src/INTERP_KERNEL/Geometric2DIntersector.hxx index 4f408f705..5a0c9f8ff 100644 --- a/src/INTERP_KERNEL/Geometric2DIntersector.hxx +++ b/src/INTERP_KERNEL/Geometric2DIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.txx b/src/INTERP_KERNEL/Geometric2DIntersector.txx index 689501161..ba4b238b1 100644 --- a/src/INTERP_KERNEL/Geometric2DIntersector.txx +++ b/src/INTERP_KERNEL/Geometric2DIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/INTERPKERNELDefines.hxx b/src/INTERP_KERNEL/INTERPKERNELDefines.hxx index c89457dbb..5177c8491 100644 --- a/src/INTERP_KERNEL/INTERPKERNELDefines.hxx +++ b/src/INTERP_KERNEL/INTERPKERNELDefines.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntegralUniformIntersector.hxx b/src/INTERP_KERNEL/IntegralUniformIntersector.hxx index c6701a78b..b98d8ff67 100644 --- a/src/INTERP_KERNEL/IntegralUniformIntersector.hxx +++ b/src/INTERP_KERNEL/IntegralUniformIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntegralUniformIntersector.txx b/src/INTERP_KERNEL/IntegralUniformIntersector.txx index efd74e62c..217ead30c 100644 --- a/src/INTERP_KERNEL/IntegralUniformIntersector.txx +++ b/src/INTERP_KERNEL/IntegralUniformIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx b/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx index 5ed816146..0c9799aa1 100644 --- a/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx +++ b/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx b/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx index 0b8b2afa7..0cad8acc3 100644 --- a/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx +++ b/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelMatrix.hxx b/src/INTERP_KERNEL/InterpKernelMatrix.hxx index 660eef399..84cc5c435 100755 --- a/src/INTERP_KERNEL/InterpKernelMatrix.hxx +++ b/src/INTERP_KERNEL/InterpKernelMatrix.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx b/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx index 988f343ce..ada00883d 100644 --- a/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx +++ b/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx b/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx index 68863a224..68fa4a389 100644 --- a/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx +++ b/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx index 06f6d325d..777ee2820 100644 --- a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx +++ b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx index 158d85193..a2a20bfda 100644 --- a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx +++ b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpKernelUtilities.hxx b/src/INTERP_KERNEL/InterpKernelUtilities.hxx index 4075c4d88..b32199546 100644 --- a/src/INTERP_KERNEL/InterpKernelUtilities.hxx +++ b/src/INTERP_KERNEL/InterpKernelUtilities.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation.hxx b/src/INTERP_KERNEL/Interpolation.hxx index 3c5eab131..8bc48a771 100644 --- a/src/INTERP_KERNEL/Interpolation.hxx +++ b/src/INTERP_KERNEL/Interpolation.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -43,7 +43,7 @@ namespace INTERP_KERNEL int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const char *method) { return fromToIntegralUniform(false,meshT,result,method); } template int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const char *method) { return fromToIntegralUniform(true,meshS,result,method); } - static void checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception); + static void CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception); template static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel); protected: diff --git a/src/INTERP_KERNEL/Interpolation.txx b/src/INTERP_KERNEL/Interpolation.txx index 201b44671..282e17da8 100644 --- a/src/INTERP_KERNEL/Interpolation.txx +++ b/src/INTERP_KERNEL/Interpolation.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -56,7 +56,7 @@ namespace INTERP_KERNEL } template - void Interpolation::checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception) + void Interpolation::CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception) { const int NB_OF_METH_MANAGED=4; const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"}; @@ -66,7 +66,7 @@ namespace INTERP_KERNEL found=(methodC==METH_MANAGED[i]); if(!found) { - std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed !"; + std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed by INTERP_KERNEL interpolators ! Supported are \"P0P0\", \"P0P1\", \"P1P0\" and \"P1P1\"."; throw INTERP_KERNEL::Exception(msg.c_str()); } srcMeth=methodC.substr(0,2); diff --git a/src/INTERP_KERNEL/Interpolation1D.hxx b/src/INTERP_KERNEL/Interpolation1D.hxx index cbb72ba25..608800bec 100755 --- a/src/INTERP_KERNEL/Interpolation1D.hxx +++ b/src/INTERP_KERNEL/Interpolation1D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation1D.txx b/src/INTERP_KERNEL/Interpolation1D.txx index b7e40eff0..9b8e051d1 100644 --- a/src/INTERP_KERNEL/Interpolation1D.txx +++ b/src/INTERP_KERNEL/Interpolation1D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2D.hxx b/src/INTERP_KERNEL/Interpolation2D.hxx index 849f3af9e..a04473aa1 100755 --- a/src/INTERP_KERNEL/Interpolation2D.hxx +++ b/src/INTERP_KERNEL/Interpolation2D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2D.txx b/src/INTERP_KERNEL/Interpolation2D.txx index 2555f4ada..c89c0fad5 100644 --- a/src/INTERP_KERNEL/Interpolation2D.txx +++ b/src/INTERP_KERNEL/Interpolation2D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2D1D.hxx b/src/INTERP_KERNEL/Interpolation2D1D.hxx index 64f0db9ed..686d7d6fa 100644 --- a/src/INTERP_KERNEL/Interpolation2D1D.hxx +++ b/src/INTERP_KERNEL/Interpolation2D1D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2D1D.txx b/src/INTERP_KERNEL/Interpolation2D1D.txx index 862c12077..365e697f6 100644 --- a/src/INTERP_KERNEL/Interpolation2D1D.txx +++ b/src/INTERP_KERNEL/Interpolation2D1D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2DCurve.cxx b/src/INTERP_KERNEL/Interpolation2DCurve.cxx index 779b9bafe..ae108e5ed 100644 --- a/src/INTERP_KERNEL/Interpolation2DCurve.cxx +++ b/src/INTERP_KERNEL/Interpolation2DCurve.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation2DCurve.hxx b/src/INTERP_KERNEL/Interpolation2DCurve.hxx index 1ddf9ed7c..2455529e9 100644 --- a/src/INTERP_KERNEL/Interpolation2DCurve.hxx +++ b/src/INTERP_KERNEL/Interpolation2DCurve.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D.cxx b/src/INTERP_KERNEL/Interpolation3D.cxx index edaad1408..351d7cdcd 100644 --- a/src/INTERP_KERNEL/Interpolation3D.cxx +++ b/src/INTERP_KERNEL/Interpolation3D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D.hxx b/src/INTERP_KERNEL/Interpolation3D.hxx index 128eedcfb..ddebd1827 100644 --- a/src/INTERP_KERNEL/Interpolation3D.hxx +++ b/src/INTERP_KERNEL/Interpolation3D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D.txx b/src/INTERP_KERNEL/Interpolation3D.txx index c293c745f..87ab6b14c 100644 --- a/src/INTERP_KERNEL/Interpolation3D.txx +++ b/src/INTERP_KERNEL/Interpolation3D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D2D.cxx b/src/INTERP_KERNEL/Interpolation3D2D.cxx index 040e654f7..280920c44 100644 --- a/src/INTERP_KERNEL/Interpolation3D2D.cxx +++ b/src/INTERP_KERNEL/Interpolation3D2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D2D.hxx b/src/INTERP_KERNEL/Interpolation3D2D.hxx index 50dea59ab..61bc68a94 100644 --- a/src/INTERP_KERNEL/Interpolation3D2D.hxx +++ b/src/INTERP_KERNEL/Interpolation3D2D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3D2D.txx b/src/INTERP_KERNEL/Interpolation3D2D.txx index b780a5606..b84b992ad 100644 --- a/src/INTERP_KERNEL/Interpolation3D2D.txx +++ b/src/INTERP_KERNEL/Interpolation3D2D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.cxx b/src/INTERP_KERNEL/Interpolation3DSurf.cxx index 8126ae823..26ca9f8cb 100644 --- a/src/INTERP_KERNEL/Interpolation3DSurf.cxx +++ b/src/INTERP_KERNEL/Interpolation3DSurf.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.hxx b/src/INTERP_KERNEL/Interpolation3DSurf.hxx index 68a05d12d..58edcac86 100644 --- a/src/INTERP_KERNEL/Interpolation3DSurf.hxx +++ b/src/INTERP_KERNEL/Interpolation3DSurf.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCC.hxx b/src/INTERP_KERNEL/InterpolationCC.hxx index e3c409592..b953d48fe 100644 --- a/src/INTERP_KERNEL/InterpolationCC.hxx +++ b/src/INTERP_KERNEL/InterpolationCC.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCC.txx b/src/INTERP_KERNEL/InterpolationCC.txx index 84a925986..7778cfad1 100644 --- a/src/INTERP_KERNEL/InterpolationCC.txx +++ b/src/INTERP_KERNEL/InterpolationCC.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCU.hxx b/src/INTERP_KERNEL/InterpolationCU.hxx index e2fef426f..6dfd2ba45 100644 --- a/src/INTERP_KERNEL/InterpolationCU.hxx +++ b/src/INTERP_KERNEL/InterpolationCU.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCU.txx b/src/INTERP_KERNEL/InterpolationCU.txx index af2cf5fae..8b4700d19 100644 --- a/src/INTERP_KERNEL/InterpolationCU.txx +++ b/src/INTERP_KERNEL/InterpolationCU.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCurve.hxx b/src/INTERP_KERNEL/InterpolationCurve.hxx index a88801482..36aaa086b 100644 --- a/src/INTERP_KERNEL/InterpolationCurve.hxx +++ b/src/INTERP_KERNEL/InterpolationCurve.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationCurve.txx b/src/INTERP_KERNEL/InterpolationCurve.txx index dc45b61ae..cd9e00355 100644 --- a/src/INTERP_KERNEL/InterpolationCurve.txx +++ b/src/INTERP_KERNEL/InterpolationCurve.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx index 94ab498ff..cdfef798c 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.cxx +++ b/src/INTERP_KERNEL/InterpolationOptions.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -66,6 +66,22 @@ const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_ const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_48_STR[]="GENERAL_48"; +void INTERP_KERNEL::InterpolationOptions::init() +{ + _print_level=0; + _intersection_type=Triangulation; + _precision=1e-12; + _median_plane=DFT_MEDIAN_PLANE; + _do_rotate=true; + _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; + _bounding_box_adjustment_abs=0.; + _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; + _orientation=0; + _measure_abs=true; + _splitting_policy=PLANAR_FACE_5; + _P1P0_bary_method=false; +} + std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const { if(_intersection_type==INTERP_KERNEL::Triangulation) diff --git a/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/INTERP_KERNEL/InterpolationOptions.hxx index 6ba269bb7..b97d3db17 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.hxx +++ b/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -22,17 +22,13 @@ #define __INTERPOLATIONOPTIONS_HXX__ #include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" #include namespace INTERP_KERNEL { typedef enum { Triangulation, Convex, Geometric2D, PointLocator } IntersectionType; - /// Type describing the different ways in which the hexahedron can be split into tetrahedra. - /// The PLANAR_* policies persume that each face is to be considered planar, while the general - /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra - /// that result from the split. - typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; /*! * \class InterpolationOptions @@ -101,21 +97,8 @@ namespace INTERP_KERNEL std::string filterInterpolationMethod(const std::string& meth) const; - void init() - { - _print_level=0; - _intersection_type=Triangulation; - _precision=1e-12; - _median_plane=DFT_MEDIAN_PLANE; - _do_rotate=true; - _bounding_box_adjustment=DFT_SURF3D_ADJ_EPS; - _bounding_box_adjustment_abs=0.; - _max_distance_for_3Dsurf_intersect=DFT_MAX_DIST_3DSURF_INTERSECT; - _orientation=0; - _measure_abs=true; - _splitting_policy=GENERAL_48; - _P1P0_bary_method=false; - } + void init(); + bool setInterpolationOptions(long print_level, std::string intersection_type, double precision, diff --git a/src/INTERP_KERNEL/InterpolationPlanar.hxx b/src/INTERP_KERNEL/InterpolationPlanar.hxx index 6d9cdd171..431c4c886 100755 --- a/src/INTERP_KERNEL/InterpolationPlanar.hxx +++ b/src/INTERP_KERNEL/InterpolationPlanar.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationPlanar.txx b/src/INTERP_KERNEL/InterpolationPlanar.txx index 07fd4d5e9..110ff9d56 100644 --- a/src/INTERP_KERNEL/InterpolationPlanar.txx +++ b/src/INTERP_KERNEL/InterpolationPlanar.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx index 80cdb8d72..46df158dd 100644 --- a/src/INTERP_KERNEL/InterpolationUtils.hxx +++ b/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3D.hxx b/src/INTERP_KERNEL/Intersector3D.hxx index 47e39122e..338c9dea9 100644 --- a/src/INTERP_KERNEL/Intersector3D.hxx +++ b/src/INTERP_KERNEL/Intersector3D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3D.txx b/src/INTERP_KERNEL/Intersector3D.txx index 67ce5941b..ea53e6f35 100644 --- a/src/INTERP_KERNEL/Intersector3D.txx +++ b/src/INTERP_KERNEL/Intersector3D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.hxx b/src/INTERP_KERNEL/Intersector3DP0P0.hxx index 7355f6eb1..d7597c59f 100644 --- a/src/INTERP_KERNEL/Intersector3DP0P0.hxx +++ b/src/INTERP_KERNEL/Intersector3DP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.txx b/src/INTERP_KERNEL/Intersector3DP0P0.txx index 5ad2fee71..ad4bab062 100644 --- a/src/INTERP_KERNEL/Intersector3DP0P0.txx +++ b/src/INTERP_KERNEL/Intersector3DP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.hxx b/src/INTERP_KERNEL/Intersector3DP0P1.hxx index 4b1dafab0..fb35393ae 100644 --- a/src/INTERP_KERNEL/Intersector3DP0P1.hxx +++ b/src/INTERP_KERNEL/Intersector3DP0P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.txx b/src/INTERP_KERNEL/Intersector3DP0P1.txx index 6abdb8828..a1ad86e74 100644 --- a/src/INTERP_KERNEL/Intersector3DP0P1.txx +++ b/src/INTERP_KERNEL/Intersector3DP0P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.hxx b/src/INTERP_KERNEL/Intersector3DP1P0.hxx index 923b0145d..2c386ec42 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P0.hxx +++ b/src/INTERP_KERNEL/Intersector3DP1P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.txx b/src/INTERP_KERNEL/Intersector3DP1P0.txx index bda1c1931..2deaf811f 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P0.txx +++ b/src/INTERP_KERNEL/Intersector3DP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx b/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx index 5adbc1fe0..41cdd6791 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx +++ b/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx b/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx index 0328a0927..930570cf4 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx +++ b/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P1.hxx b/src/INTERP_KERNEL/Intersector3DP1P1.hxx index a636a6392..6ec68eac2 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P1.hxx +++ b/src/INTERP_KERNEL/Intersector3DP1P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Intersector3DP1P1.txx b/src/INTERP_KERNEL/Intersector3DP1P1.txx index f62032267..06ee6c98e 100644 --- a/src/INTERP_KERNEL/Intersector3DP1P1.txx +++ b/src/INTERP_KERNEL/Intersector3DP1P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU.hxx b/src/INTERP_KERNEL/IntersectorCU.hxx index fac8c96c5..fe1cf2a0f 100644 --- a/src/INTERP_KERNEL/IntersectorCU.hxx +++ b/src/INTERP_KERNEL/IntersectorCU.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU.txx b/src/INTERP_KERNEL/IntersectorCU.txx index 1d4d1451c..26ac82560 100644 --- a/src/INTERP_KERNEL/IntersectorCU.txx +++ b/src/INTERP_KERNEL/IntersectorCU.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU1D.hxx b/src/INTERP_KERNEL/IntersectorCU1D.hxx index ec0a9d874..1c26b2f20 100644 --- a/src/INTERP_KERNEL/IntersectorCU1D.hxx +++ b/src/INTERP_KERNEL/IntersectorCU1D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU1D.txx b/src/INTERP_KERNEL/IntersectorCU1D.txx index 751e94fe0..30fb35f1e 100644 --- a/src/INTERP_KERNEL/IntersectorCU1D.txx +++ b/src/INTERP_KERNEL/IntersectorCU1D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU2D.hxx b/src/INTERP_KERNEL/IntersectorCU2D.hxx index 816fa1b35..2391191e6 100644 --- a/src/INTERP_KERNEL/IntersectorCU2D.hxx +++ b/src/INTERP_KERNEL/IntersectorCU2D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU2D.txx b/src/INTERP_KERNEL/IntersectorCU2D.txx index cade7ceb3..36ebd0b89 100644 --- a/src/INTERP_KERNEL/IntersectorCU2D.txx +++ b/src/INTERP_KERNEL/IntersectorCU2D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU3D.hxx b/src/INTERP_KERNEL/IntersectorCU3D.hxx index 2e48dafa1..cea435370 100644 --- a/src/INTERP_KERNEL/IntersectorCU3D.hxx +++ b/src/INTERP_KERNEL/IntersectorCU3D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/IntersectorCU3D.txx b/src/INTERP_KERNEL/IntersectorCU3D.txx index 81ff0046a..06f3a59a5 100644 --- a/src/INTERP_KERNEL/IntersectorCU3D.txx +++ b/src/INTERP_KERNEL/IntersectorCU3D.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2012 OPEN CASCADE +// Copyright (C) 2009-2013 OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Log.hxx b/src/INTERP_KERNEL/Log.hxx index a994d5541..68fa85cf7 100644 --- a/src/INTERP_KERNEL/Log.hxx +++ b/src/INTERP_KERNEL/Log.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Makefile.am b/src/INTERP_KERNEL/Makefile.am index 25258d67c..149a7ee2e 100644 --- a/src/INTERP_KERNEL/Makefile.am +++ b/src/INTERP_KERNEL/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,8 @@ lib_LTLIBRARIES = libinterpkernel.la salomeinclude_HEADERS = \ BBTree.txx \ +BBTreePts.txx \ +BBTreeDst.txx \ BoundingBox.hxx \ CellModel.hxx \ ConvexIntersector.hxx \ @@ -218,6 +220,7 @@ dist_libinterpkernel_la_SOURCES = \ TranslationRotationMatrix.cxx \ TetraAffineTransform.cxx \ CellModel.cxx \ + VolSurfUser.cxx \ UnitTetraIntersectionBary.cxx \ InterpolationOptions.cxx \ DirectedBoundingBox.cxx \ diff --git a/src/INTERP_KERNEL/MeshElement.cxx b/src/INTERP_KERNEL/MeshElement.cxx index 9d44bc7c7..60e485061 100644 --- a/src/INTERP_KERNEL/MeshElement.cxx +++ b/src/INTERP_KERNEL/MeshElement.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/MeshElement.hxx b/src/INTERP_KERNEL/MeshElement.hxx index 484d9f920..7a5510101 100644 --- a/src/INTERP_KERNEL/MeshElement.hxx +++ b/src/INTERP_KERNEL/MeshElement.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/MeshElement.txx b/src/INTERP_KERNEL/MeshElement.txx index 0388a4e5d..51500d983 100644 --- a/src/INTERP_KERNEL/MeshElement.txx +++ b/src/INTERP_KERNEL/MeshElement.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/MeshRegion.hxx b/src/INTERP_KERNEL/MeshRegion.hxx index d1e51f9cc..4a9dca523 100644 --- a/src/INTERP_KERNEL/MeshRegion.hxx +++ b/src/INTERP_KERNEL/MeshRegion.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/MeshRegion.txx b/src/INTERP_KERNEL/MeshRegion.txx index 4b79b2fdd..b36eb8bc0 100644 --- a/src/INTERP_KERNEL/MeshRegion.txx +++ b/src/INTERP_KERNEL/MeshRegion.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/MeshUtils.hxx b/src/INTERP_KERNEL/MeshUtils.hxx index 908c0d03a..61d2e9cfd 100644 --- a/src/INTERP_KERNEL/MeshUtils.hxx +++ b/src/INTERP_KERNEL/MeshUtils.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx index 9b89117b2..21b3e929b 100644 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx index 0d4a9eb85..46c2e05ff 100644 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersector.hxx b/src/INTERP_KERNEL/PlanarIntersector.hxx index e1552c5cf..ae9a85374 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.hxx +++ b/src/INTERP_KERNEL/PlanarIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx index ff351fb89..b8fe7aafc 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.txx +++ b/src/INTERP_KERNEL/PlanarIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx index f0e96825c..8f2db805f 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx index c62357b1a..0abe6788f 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx index 5f1107b11..ebe8ec9c1 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx index 090929db6..45d6444dd 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx index c5f22d409..dd3f5f4b7 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx index 902c86a22..3cd1e2507 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx index 50dc04987..13c1d74f9 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx index 22ebb93a9..55c743cc7 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx index 2d3260316..523519044 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx index a8bd8bc8e..a0d992117 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx index 47def33d0..88587588e 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx index 0f0ab9582..37de732d5 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx index 26f77918a..5751c5a99 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx index 9507a63b4..a89468cf9 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx index d43edaa58..371f4ae8c 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx index 61bdd13f1..ee1f9c8d8 100644 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx b/src/INTERP_KERNEL/PointLocator2DIntersector.hxx index 8971dc9e7..8da0ccf8a 100644 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx +++ b/src/INTERP_KERNEL/PointLocator2DIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.txx b/src/INTERP_KERNEL/PointLocator2DIntersector.txx index 14429bb5e..581d08c7c 100644 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.txx +++ b/src/INTERP_KERNEL/PointLocator2DIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx index 3b4081ec2..d157e4e1b 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx index 5cfa1321c..cc8e7c2d3 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx index 345bac944..5c875192d 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx index 33d9d6883..386bc432f 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx index dab5aa63c..e9470e6b7 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx index bad0d01cb..a222955c4 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx index ec88c8274..2faaa3a3f 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx index d6baf689f..c4e02ef1b 100644 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PointLocatorAlgos.txx b/src/INTERP_KERNEL/PointLocatorAlgos.txx index 0ac908044..24705f4fe 100644 --- a/src/INTERP_KERNEL/PointLocatorAlgos.txx +++ b/src/INTERP_KERNEL/PointLocatorAlgos.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.hxx b/src/INTERP_KERNEL/PolygonAlgorithms.hxx index dc072352e..5cb34812a 100644 --- a/src/INTERP_KERNEL/PolygonAlgorithms.hxx +++ b/src/INTERP_KERNEL/PolygonAlgorithms.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.txx b/src/INTERP_KERNEL/PolygonAlgorithms.txx index 3f1bf175f..a6d7b4b74 100644 --- a/src/INTERP_KERNEL/PolygonAlgorithms.txx +++ b/src/INTERP_KERNEL/PolygonAlgorithms.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx index 519660000..f1a85b31c 100644 --- a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx index 92418804d..ce3d1a10c 100644 --- a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx index fd039593c..2b8c2ae78 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx index ba5ea83b8..1cddccdca 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -84,7 +84,10 @@ namespace INTERP_KERNEL { double volume = 0.; for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { volume += (*iter)->intersectSourceCell(*iterCellS); + (*iter)->clearVolumesCache(); + } if(volume!=0.) res[targetCell].insert(std::make_pair(OTT::indFC(*iterCellS), volume)); } diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx index 75ef149ba..bd51372d5 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx index f41bca07d..292800556 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx index 486f35394..4cdc4e48a 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx index 7e56de719..0e79ab186 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx index 982586ecb..0fadeeb32 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx index 044e68acb..49d537647 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx index 346a14e33..7d44c882f 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx index 3d3cfb88d..f24f137db 100644 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/RegionNode.hxx b/src/INTERP_KERNEL/RegionNode.hxx index 14d482e28..10c5f8d23 100644 --- a/src/INTERP_KERNEL/RegionNode.hxx +++ b/src/INTERP_KERNEL/RegionNode.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/SplitterTetra.hxx b/src/INTERP_KERNEL/SplitterTetra.hxx index d535b9c37..068c51100 100644 --- a/src/INTERP_KERNEL/SplitterTetra.hxx +++ b/src/INTERP_KERNEL/SplitterTetra.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -26,14 +26,113 @@ #include "InterpKernelHashMap.hxx" #include "VectorUtils.hxx" -#include -#include #include +#include +#include #include #include namespace INTERP_KERNEL { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + + static const int SPLIT_NODES_5[20] = /* WHY not all well oriented ???? */ + { + 0, 1, 5, 2, + 0, 4, 5, 7, + 0, 3, 7, 2, + 5, 6, 7, 2, + 0, 2, 5, 7 + }; + + static const int SPLIT_NODES_5_WO[20] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ + { + 0, 5, 1, 2, + 0, 4, 5, 7, + 0, 3, 7, 2, + 5, 7, 6, 2, + 0, 5, 2, 7 + }; + + static const int SPLIT_NODES_6[24] = /* WHY all badly oriented ???? */ + { + 0, 1, 5, 6, + 0, 2, 1, 6, + 0, 5, 4, 6, + 0, 4, 7, 6, + 0, 3, 2, 6, + 0, 7, 3, 6 + }; + + static const int SPLIT_NODES_6_WO[24] = /* WO for well oriented !!! normals of 3 first points are OUTSIDE the TETRA4 */ + { + 0, 5, 1, 6, + 0, 1, 2, 6, + 0, 4, 5, 6, + 0, 7, 4, 6, + 0, 2, 3, 6, + 0, 3, 7, 6 + }; + + // Each sub-node is the barycenter of 4 other nodes. + // For the faces, these are on the orignal mesh. + // For the barycenter, the four face sub-nodes are used. + static const int GENERAL_24_SUB_NODES[28] = + { + 0,1,4,5,// sub-node 8 (face) + 0,1,2,3,// sub-node 9 (face) + 0,3,4,7,// sub-node 10 (face) + 1,2,5,6,// sub-node 11 (face) + 4,5,6,7,// sub-node 12 (face) + 2,3,6,7,// sub-node 13 (face) + 8,9,10,11// sub-node 14 (cell) + }; + + static const int TETRA_EDGES_GENERAL_24[48] = + { + // face with center 8 + 0,1, + 1,5, + 5,4, + 4,0, + // face with center 9 + 0,1, + 1,2, + 2,3, + 3,0, + // face with center 10 + 0,4, + 4,7, + 7,3, + 3,0, + // face with center 11 + 1,5, + 5,6, + 6,2, + 2,1, + // face with center 12 + 5,6, + 6,7, + 7,4, + 4,5, + // face with center 13 + 2,6, + 6,7, + 7,3, + 3,2 + }; + /** * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. * diff --git a/src/INTERP_KERNEL/SplitterTetra.txx b/src/INTERP_KERNEL/SplitterTetra.txx index e36dd0ae5..9e5d32c59 100644 --- a/src/INTERP_KERNEL/SplitterTetra.txx +++ b/src/INTERP_KERNEL/SplitterTetra.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -1029,30 +1029,7 @@ namespace INTERP_KERNEL */ template void SplitterTetra2::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - // Schema according to which the splitting is performed. - // Each line represents one tetrahedron. The numbering is as follows : - // - // 7 ------ 6 - // /| /| - // / | / | - // 3 ------ 2 | - // | | | | - // | | | | - // | 4-----|- 5 - // | / | / - // 0 ------ 1 - - - static const int SPLIT_NODES_5[20] = - { - 0, 1, 5, 2, - 0, 4, 5, 7, - 0, 3, 7, 2, - 5, 6, 7, 2, - 0, 2, 5, 7 - }; - + { // create tetrahedra for(int i = 0; i < 5; ++i) { @@ -1078,29 +1055,6 @@ namespace INTERP_KERNEL template void SplitterTetra2::sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) { - // Schema according to which the splitting is performed. - // Each line represents one tetrahedron. The numbering is as follows : - // - // 7 ------ 6 - // /| /| - // / | / | - // 3 ------ 2 | - // | | | | - // | | | | - // | 4-----|- 5 - // | / | / - // 0 ------ 1 - - static const int SPLIT_NODES_6[24] = - { - 0, 1, 5, 6, - 0, 2, 1, 6, - 0, 5, 4, 6, - 0, 4, 7, 6, - 0, 3, 2, 6, - 0, 7, 3, 6 - }; - for(int i = 0; i < 6; ++i) { const double* nodes[4]; @@ -1128,39 +1082,6 @@ namespace INTERP_KERNEL // The two nodes of the original mesh cell used in each tetrahedron. // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes - static const int TETRA_EDGES[48] = - { - // face with center 9 - 0,1, - 1,5, - 5,4, - 4,0, - // face with center 10 - 0,1, - 1,2, - 2,3, - 3,0, - // face with center 11 - 0,4, - 4,7, - 7,3, - 3,0, - // face with center 12 - 1,5, - 5,6, - 6,2, - 2,1, - // face with center 13 - 5,6, - 6,7, - 7,4, - 4,5, - // face with center 14 - 2,6, - 6,7, - 7,3, - 3,2 - }; // nodes to use for tetrahedron const double* nodes[4]; @@ -1177,8 +1098,8 @@ namespace INTERP_KERNEL for(int j = 0; j < 4; ++j) { const int row = 4*(faceCenterNode - 8) + j; - conn[2] = TETRA_EDGES[2*row]; - conn[3] = TETRA_EDGES[2*row + 1]; + conn[2] = TETRA_EDGES_GENERAL_24[2*row]; + conn[3] = TETRA_EDGES_GENERAL_24[2*row + 1]; nodes[2] = getCoordsOfSubNode(conn[2]); nodes[3] = getCoordsOfSubNode(conn[3]); @@ -1341,20 +1262,6 @@ namespace INTERP_KERNEL { case GENERAL_24: { - // Each sub-node is the barycenter of 4 other nodes. - // For the faces, these are on the orignal mesh. - // For the barycenter, the four face sub-nodes are used. - static const int GENERAL_24_SUB_NODES[28] = - { - 0,1,4,5,// sub-node 9 (face) - 0,1,2,3,// sub-node 10 (face) - 0,3,4,7,// sub-node 11 (face) - 1,2,5,6,// sub-node 12 (face) - 4,5,6,7,// sub-node 13 (face) - 2,3,6,7,// sub-node 14 (face) - 8,9,10,11// sub-node 15 (cell) - }; - for(int i = 0; i < 7; ++i) { double* barycenter = new double[3]; diff --git a/src/INTERP_KERNEL/TargetIntersector.hxx b/src/INTERP_KERNEL/TargetIntersector.hxx index c1a898a99..016c8e1e1 100644 --- a/src/INTERP_KERNEL/TargetIntersector.hxx +++ b/src/INTERP_KERNEL/TargetIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TetraAffineTransform.cxx b/src/INTERP_KERNEL/TetraAffineTransform.cxx index 0ca3f599e..87690657c 100644 --- a/src/INTERP_KERNEL/TetraAffineTransform.cxx +++ b/src/INTERP_KERNEL/TetraAffineTransform.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TetraAffineTransform.hxx b/src/INTERP_KERNEL/TetraAffineTransform.hxx index 303c8f9b4..de1e8ee6c 100644 --- a/src/INTERP_KERNEL/TetraAffineTransform.hxx +++ b/src/INTERP_KERNEL/TetraAffineTransform.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TransformedTriangle.cxx b/src/INTERP_KERNEL/TransformedTriangle.cxx index 1e3f6a484..f003a343f 100644 --- a/src/INTERP_KERNEL/TransformedTriangle.cxx +++ b/src/INTERP_KERNEL/TransformedTriangle.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TransformedTriangle.hxx b/src/INTERP_KERNEL/TransformedTriangle.hxx index 8372c4a38..650de1653 100644 --- a/src/INTERP_KERNEL/TransformedTriangle.hxx +++ b/src/INTERP_KERNEL/TransformedTriangle.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TransformedTriangleInline.hxx b/src/INTERP_KERNEL/TransformedTriangleInline.hxx index 1576ad804..f3f9e7641 100644 --- a/src/INTERP_KERNEL/TransformedTriangleInline.hxx +++ b/src/INTERP_KERNEL/TransformedTriangleInline.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx b/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx index 37cf82551..524490c34 100644 --- a/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx +++ b/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TransformedTriangleMath.cxx b/src/INTERP_KERNEL/TransformedTriangleMath.cxx index 5d7cf02ab..d5e340f65 100644 --- a/src/INTERP_KERNEL/TransformedTriangleMath.cxx +++ b/src/INTERP_KERNEL/TransformedTriangleMath.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx index 3c28c1320..7e2acd5c8 100644 --- a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx +++ b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx index e2186fc54..c6dc70d86 100644 --- a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx +++ b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TriangulationIntersector.hxx b/src/INTERP_KERNEL/TriangulationIntersector.hxx index 170a8f120..ae08664ed 100644 --- a/src/INTERP_KERNEL/TriangulationIntersector.hxx +++ b/src/INTERP_KERNEL/TriangulationIntersector.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/TriangulationIntersector.txx b/src/INTERP_KERNEL/TriangulationIntersector.txx index 53363c96b..72eb7dd98 100644 --- a/src/INTERP_KERNEL/TriangulationIntersector.txx +++ b/src/INTERP_KERNEL/TriangulationIntersector.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx index f087eb584..a7b489dbe 100644 --- a/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx +++ b/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx index 0e7f70b08..82ceae0be 100644 --- a/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx +++ b/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx index f533492df..746cbf9fc 100644 --- a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx +++ b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx index e326ec4ae..54b2d08fe 100644 --- a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx +++ b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/VectorUtils.hxx b/src/INTERP_KERNEL/VectorUtils.hxx index 3c6832344..bf7d5ec90 100644 --- a/src/INTERP_KERNEL/VectorUtils.hxx +++ b/src/INTERP_KERNEL/VectorUtils.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNEL/VolSurfFormulae.hxx b/src/INTERP_KERNEL/VolSurfFormulae.hxx index c59737068..b588ec351 100644 --- a/src/INTERP_KERNEL/VolSurfFormulae.hxx +++ b/src/INTERP_KERNEL/VolSurfFormulae.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,8 @@ #include "InterpolationUtils.hxx" #include "InterpKernelException.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" #include "InterpKernelGeo2DQuadraticPolygon.hxx" #include @@ -52,6 +54,18 @@ namespace INTERP_KERNEL return sqrt(ret); } } + + inline double calculateLgthForSeg3(const double *begin, const double *end, const double *middle, int spaceDim) + { + if(spaceDim==2) + { + Edge *ed=Edge::BuildEdgeFrom3Points(begin,middle,end); + double ret=ed->getCurveLength(); ed->decrRef(); + return ret; + } + else + return calculateLgthForSeg2(begin,end,spaceDim); + } // =========================== // Calculate Area for triangle @@ -495,6 +509,78 @@ namespace INTERP_KERNEL } } + template + inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res) + { + double area[3]; + areaVectorOfPolygon(connec,lgth,coords,area); + double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]); + if(norm>std::numeric_limits::min()) + { + area[0]/=norm; area[1]/=norm; area[2]/=norm; + res[0]=0.; res[1]=0.; res[2]=0.; + for(int i=1;i::coo2C(connec[0])]+ + coords[3*OTT::coo2C(connec[i])]+ + coords[3*OTT::coo2C(connec[i+1])])/3.; + v[1]=(coords[3*OTT::coo2C(connec[0])+1]+ + coords[3*OTT::coo2C(connec[i])+1]+ + coords[3*OTT::coo2C(connec[i+1])+1])/3.; + v[2]=(coords[3*OTT::coo2C(connec[0])+2]+ + coords[3*OTT::coo2C(connec[i])+2]+ + coords[3*OTT::coo2C(connec[i+1])+2])/3.; + ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]}; + areaVectorOfPolygon(tmpConn,3,coords,tmpArea); + double norm2=sqrt(tmpArea[0]*tmpArea[0]+tmpArea[1]*tmpArea[1]+tmpArea[2]*tmpArea[2]); + if(norm2>1e-12) + { + tmpArea[0]/=norm2; tmpArea[1]/=norm2; tmpArea[2]/=norm2; + double signOfArea=area[0]*tmpArea[0]+area[1]*tmpArea[1]+area[2]*tmpArea[2]; + res[0]+=signOfArea*norm2*v[0]/norm; res[1]+=signOfArea*norm2*v[1]/norm; res[2]+=signOfArea*norm2*v[2]/norm; + } + } + } + else + { + res[0]=0.; res[1]=0.; res[2]=0.; + if(lgth<1) + throw INTERP_KERNEL::Exception("computePolygonBarycenter3D : lgth of polygon is < 1 !"); + norm=0.; + double v[3]; + for(int i=0;i::coo2C(connec[(i+1)%lgth])]-coords[3*OTT::coo2C(connec[i])]; + v[1]=coords[3*OTT::coo2C(connec[(i+1)%lgth])+1]-coords[3*OTT::coo2C(connec[i])+1]; + v[2]=coords[3*OTT::coo2C(connec[(i+1)%lgth])+2]-coords[3*OTT::coo2C(connec[i])+2]; + double norm2=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); + res[0]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])]+coords[3*OTT::coo2C(connec[i])])/2.*norm2; + res[1]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])+1]+coords[3*OTT::coo2C(connec[i])+1])/2.*norm2; + res[2]+=(coords[3*OTT::coo2C(connec[(i+1)%lgth])+2]+coords[3*OTT::coo2C(connec[i])+2])/2.*norm2; + norm+=norm2; + } + if(norm>std::numeric_limits::min()) + { + res[0]/=norm; res[1]/=norm; res[2]/=norm; + return; + } + else + { + res[0]=0.; res[1]=0.; res[2]=0.; + for(int i=0;i::coo2C(connec[i])]; + res[1]+=coords[3*OTT::coo2C(connec[i])+1]; + res[2]+=coords[3*OTT::coo2C(connec[i])+2]; + } + res[0]/=lgth; res[1]/=lgth; res[2]/=lgth; + return; + } + } + } + inline double integrationOverA3DLine(double u1, double v1, double u2, double v2, double A, double B, double C) { return (u1-u2)*(6.*C*C*(v1+v2)+B*B*(v1*v1*v1+v1*v1*v2+v1*v2*v2+v2*v2*v2)+A*A*(2.*u1*u2*(v1+v2)+u1*u1*(3.*v1+v2)+u2*u2*(v1+3.*v2))+ @@ -515,6 +601,8 @@ namespace INTERP_KERNEL double normal[3]; areaVectorOfPolygon(work,nbOfNodesOfCurFace,coords,normal); double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); + if(normOfNormal::min()) + continue; normal[0]/=normOfNormal; normal[1]/=normOfNormal; normal[2]/=normOfNormal; double u[2]={normal[1],-normal[0]}; double s=sqrt(u[0]*u[0]+u[1]*u[1]); @@ -561,7 +649,32 @@ namespace INTERP_KERNEL work=work2+1; } double vol=calculateVolumeForPolyh2(connec,lgth,coords); - res[0]/=vol; res[1]/=vol; res[2]/=vol; + if(fabs(vol)>std::numeric_limits::min()) + { + res[0]/=vol; res[1]/=vol; res[2]/=vol; + } + else + { + double sum=0.; + res[0]=0.; res[1]=0.; res[2]=0.; + work=connec; + for(std::size_t i=0;i(work,nbOfNodesOfCurFace,coords,normal); + double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); + if(normOfNormal::min()) + continue; + sum+=normOfNormal; + double tmpBary[3]; + computePolygonBarycenter3D(work,nbOfNodesOfCurFace,coords,tmpBary); + res[0]+=normOfNormal*tmpBary[0]; res[1]+=normOfNormal*tmpBary[1]; res[2]+=normOfNormal*tmpBary[2]; + work=work2+1; + } + res[0]/=sum; res[1]/=sum; res[2]/=sum; + } } // ============================================================================================================================================ @@ -669,55 +782,53 @@ namespace INTERP_KERNEL bary[i]=temp/nbPts; } } - - template - inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) + + inline void computePolygonBarycenter2DEngine(double **coords, int lgth, double *res) { double area=0.; res[0]=0.; res[1]=0.; for(int i=0;i::coo2C(connec[i])]*coords[2*OTT::coo2C(connec[(i+1)%lgth])+1]- - coords[2*OTT::coo2C(connec[i])+1]*coords[2*OTT::coo2C(connec[(i+1)%lgth])]; + double cp=coords[i][0]*coords[(i+1)%lgth][1]-coords[i][1]*coords[(i+1)%lgth][0]; area+=cp; - res[0]+=cp*(coords[2*OTT::coo2C(connec[i])]+coords[2*OTT::coo2C(connec[(i+1)%lgth])]); - res[1]+=cp*(coords[2*OTT::coo2C(connec[i])+1]+coords[2*OTT::coo2C(connec[(i+1)%lgth])+1]); + res[0]+=cp*(coords[i][0]+coords[(i+1)%lgth][0]); + res[1]+=cp*(coords[i][1]+coords[(i+1)%lgth][1]); } res[0]/=3.*area; res[1]/=3.*area; } template - inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res) + inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) { - double area[3]; - areaVectorOfPolygon(connec,lgth,coords,area); - double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]); - area[0]/=norm; area[1]/=norm; area[2]/=norm; - res[0]=0.; res[1]=0.; res[2]=0.; - for(int i=1;i(coords+2*OTT::coo2C(connec[i])); + computePolygonBarycenter2DEngine(coords2,lgth,res); + delete [] coords2; + } + + inline void computeQPolygonBarycenter2D(double **coords, int nbOfPtsInPolygs, int spaceDim, double *res) + { + if(nbOfPtsInPolygs%2==0) { - double v[3]; - double tmpArea[3]; - v[0]=(coords[3*OTT::coo2C(connec[0])]+ - coords[3*OTT::coo2C(connec[i])]+ - coords[3*OTT::coo2C(connec[i+1])])/3.; - v[1]=(coords[3*OTT::coo2C(connec[0])+1]+ - coords[3*OTT::coo2C(connec[i])+1]+ - coords[3*OTT::coo2C(connec[i+1])+1])/3.; - v[2]=(coords[3*OTT::coo2C(connec[0])+2]+ - coords[3*OTT::coo2C(connec[i])+2]+ - coords[3*OTT::coo2C(connec[i+1])+2])/3.; - ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]}; - areaVectorOfPolygon(tmpConn,3,coords,tmpArea); - double norm2=sqrt(tmpArea[0]*tmpArea[0]+tmpArea[1]*tmpArea[1]+tmpArea[2]*tmpArea[2]); - if(norm2>1e-12) + if(spaceDim==2) { - tmpArea[0]/=norm2; tmpArea[1]/=norm2; tmpArea[2]/=norm2; - double signOfArea=area[0]*tmpArea[0]+area[1]*tmpArea[1]+area[2]*tmpArea[2]; - res[0]+=signOfArea*norm2*v[0]/norm; res[1]+=signOfArea*norm2*v[1]/norm; res[2]+=signOfArea*norm2*v[2]/norm; + std::vector nodes(nbOfPtsInPolygs); + for(int i=0;igetBarycenter(res); + delete pol; } - } + else + return computePolygonBarycenter2DEngine(coords,nbOfPtsInPolygs/2,res); + } + else + { + std::ostringstream oss; oss << "INTERP_KERNEL::computeQPolygonBarycenter2D : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } } diff --git a/src/INTERP_KERNEL/VolSurfUser.cxx b/src/INTERP_KERNEL/VolSurfUser.cxx new file mode 100644 index 000000000..8165dd396 --- /dev/null +++ b/src/INTERP_KERNEL/VolSurfUser.cxx @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "VolSurfUser.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include +#include +#include + +namespace INTERP_KERNEL +{ + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint) throw(INTERP_KERNEL::Exception) + { + double dx=pt1Seg2[0]-pt0Seg2[0],dy=pt1Seg2[1]-pt0Seg2[1]; + double norm=sqrt(dx*dx+dy*dy); + if(norm==0.) + return (pt[0]-pt0Seg2[0])*(pt[0]-pt0Seg2[0])+(pt[1]-pt0Seg2[1])*(pt[1]-pt0Seg2[1]);//return std::numeric_limits::max(); + dx/=norm; dy/=norm; + double dx2=pt[0]-pt0Seg2[0],dy2=pt[1]-pt0Seg2[1]; + double dotP=(dx2*dx+dy2*dy); + if(dotP<0. || dotP>norm) + return dotP<0.?(pt[0]-pt0Seg2[0])*(pt[0]-pt0Seg2[0])+(pt[1]-pt0Seg2[1])*(pt[1]-pt0Seg2[1]):(pt[0]-pt1Seg2[0])*(pt[0]-pt1Seg2[0])+(pt[1]-pt1Seg2[1])*(pt[1]-pt1Seg2[1]); + nbOfHint++; + double x=pt0Seg2[0]+dotP*dx,y=pt0Seg2[1]+dotP*dy; + return (x-pt[0])*(x-pt[0])+(y-pt[1])*(y-pt[1]); + } + + double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception) + { + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(pt0Tri3,pt1Tri3,pt2Tri3,matrix)) + return std::numeric_limits::max(); + double xy0[2],xy1[2],xy2[2],xy[2]; xy0[0]=0.; xy0[1]=0.; + xy1[0]=matrix[0]*pt1Tri3[0]+matrix[1]*pt1Tri3[1]+matrix[2]*pt1Tri3[2]+matrix[3]; xy1[1]=0.; + xy2[0]=matrix[0]*pt2Tri3[0]+matrix[1]*pt2Tri3[1]+matrix[2]*pt2Tri3[2]+matrix[3]; + xy2[1]=matrix[4]*pt2Tri3[0]+matrix[5]*pt2Tri3[1]+matrix[6]*pt2Tri3[2]+matrix[7]; + xy[0]=matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3]; + xy[1]=matrix[4]*pt[0]+matrix[5]*pt[1]+matrix[6]*pt[2]+matrix[7]; + double z=matrix[8]*pt[0]+matrix[9]*pt[1]+matrix[10]*pt[2]+matrix[11]; + double ret=std::numeric_limits::max(); + std::size_t nbOfHint=0; + if(xy[0]>0. && xy[0](),1./((double)nbOfEdges))); + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix)) + return std::numeric_limits::max(); + INTERP_KERNEL::AutoPtr ptXY=new double[2*nbOfEdges]; ptXY[0]=0.; ptXY[1]=0.; + ptXY[2]=matrix[0]*coords[3*connOfPolygonBg[1]]+matrix[1]*coords[3*connOfPolygonBg[1]+1]+matrix[2]*coords[3*connOfPolygonBg[1]+2]+matrix[3]; ptXY[3]=0.; + for(std::size_t i=2;i::max(); + std::size_t nbOfHint=0; + for(std::size_t i=0;i void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); + + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint) throw(INTERP_KERNEL::Exception); + + double DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3) throw(INTERP_KERNEL::Exception); + + double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) throw(INTERP_KERNEL::Exception); + + bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix); } #endif diff --git a/src/INTERP_KERNEL/VolSurfUser.txx b/src/INTERP_KERNEL/VolSurfUser.txx index adfb96552..4833a91b3 100644 --- a/src/INTERP_KERNEL/VolSurfUser.txx +++ b/src/INTERP_KERNEL/VolSurfUser.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -34,13 +34,19 @@ namespace INTERP_KERNEL switch(type) { case INTERP_KERNEL::NORM_SEG2 : - case INTERP_KERNEL::NORM_SEG3 : case INTERP_KERNEL::NORM_SEG4 : { int N1 = OTT::coo2C(connec[0]); int N2 = OTT::coo2C(connec[1]); return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM); } + case INTERP_KERNEL::NORM_SEG3 : + { + int beginNode = OTT::coo2C(connec[0]); + int endNode = OTT::coo2C(connec[1]); + int middleNode = OTT::coo2C(connec[2]); + return INTERP_KERNEL::calculateLgthForSeg3(coords+(SPACEDIM*beginNode),coords+(SPACEDIM*endNode),coords+(SPACEDIM*middleNode),SPACEDIM); + } case INTERP_KERNEL::NORM_TRI3 : { int N1 = OTT::coo2C(connec[0]); @@ -115,6 +121,7 @@ namespace INTERP_KERNEL delete [] pts; return val; } + break; case INTERP_KERNEL::NORM_TETRA4 : case INTERP_KERNEL::NORM_TETRA10 : { @@ -231,7 +238,6 @@ namespace INTERP_KERNEL switch(type) { case NORM_SEG2: - case NORM_SEG3: case NORM_SEG4: { std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), @@ -240,8 +246,30 @@ namespace INTERP_KERNEL std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),0.5)); break; } + case NORM_SEG3: + { + if(SPACEDIM==2) + { + Edge *ed=Edge::BuildEdgeFrom3Points(coords+2*OTT::coo2C(connec[0]),coords+2*OTT::coo2C(connec[2]),coords+2*OTT::coo2C(connec[1])); + ed->getBarycenter(res); + ed->decrRef(); + } + else if(SPACEDIM==1) + { + *res=(coords[OTT::coo2C(connec[0])]+coords[OTT::coo2C(connec[1])])/2.; + } + else if(SPACEDIM==3) + { + std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), + coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),0.5)); + } + else + throw INTERP_KERNEL::Exception("computeBarycenter for SEG3 only SPACEDIM 1,2 or 3 supported !"); + break; + } case NORM_TRI3: - case NORM_TRI6: case NORM_TRI7: { std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), @@ -251,6 +279,25 @@ namespace INTERP_KERNEL std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),1./3.)); break; } + case NORM_TRI6: + { + if(SPACEDIM==2) + { + double *pts[6]; + pts[0] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[0])); + pts[1] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[1])); + pts[2] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[2])); + pts[3] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[3])); + pts[4] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[4])); + pts[5] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[5])); + computeQPolygonBarycenter2D(pts,6,2,res); + } + else if(SPACEDIM==3) + computePolygonBarycenter3D(connec,lgth/2,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } case NORM_QUAD4: case NORM_POLYGON: { @@ -265,13 +312,41 @@ namespace INTERP_KERNEL case NORM_QUAD8: { if(SPACEDIM==2) - computePolygonBarycenter2D(connec,lgth/2,coords,res); + { + double *pts[8]; + pts[0] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[0])); + pts[1] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[1])); + pts[2] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[2])); + pts[3] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[3])); + pts[4] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[4])); + pts[5] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[5])); + pts[6] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[6])); + pts[7] = const_cast(coords+SPACEDIM*OTT::coo2C(connec[7])); + computeQPolygonBarycenter2D(pts,8,2,res); + } + else if(SPACEDIM==3) + computePolygonBarycenter3D(connec,lgth/2,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } + case INTERP_KERNEL::NORM_QPOLYG : + { + if(SPACEDIM==2) + { + double **pts=new double *[lgth]; + for(int i=0;i(coords+2*OTT::coo2C(connec[i])); + computeQPolygonBarycenter2D(pts,lgth,2,res); + delete [] pts; + } else if(SPACEDIM==3) computePolygonBarycenter3D(connec,lgth/2,coords,res); else throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); break; } + break; case NORM_TETRA4: { res[0]=coords[3*OTT::coo2C(connec[0])]; diff --git a/src/INTERP_KERNELTest/BBTreeTest.cxx b/src/INTERP_KERNELTest/BBTreeTest.cxx index b827bea2f..8f31c2bcf 100644 --- a/src/INTERP_KERNELTest/BBTreeTest.cxx +++ b/src/INTERP_KERNELTest/BBTreeTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/BBTreeTest.hxx b/src/INTERP_KERNELTest/BBTreeTest.hxx index 85faf0f5d..00e82688d 100644 --- a/src/INTERP_KERNELTest/BBTreeTest.hxx +++ b/src/INTERP_KERNELTest/BBTreeTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/BasicMainTest.hxx b/src/INTERP_KERNELTest/BasicMainTest.hxx index 914473eb8..49b6061d4 100644 --- a/src/INTERP_KERNELTest/BasicMainTest.hxx +++ b/src/INTERP_KERNELTest/BasicMainTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/CMakeLists.txt b/src/INTERP_KERNELTest/CMakeLists.txt index 658a3cee1..1a2750300 100644 --- a/src/INTERP_KERNELTest/CMakeLists.txt +++ b/src/INTERP_KERNELTest/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/CppUnitTest.cxx b/src/INTERP_KERNELTest/CppUnitTest.cxx index 192122225..993fd6b54 100644 --- a/src/INTERP_KERNELTest/CppUnitTest.cxx +++ b/src/INTERP_KERNELTest/CppUnitTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/CppUnitTest.hxx b/src/INTERP_KERNELTest/CppUnitTest.hxx index 8764fa665..549541a3b 100644 --- a/src/INTERP_KERNELTest/CppUnitTest.hxx +++ b/src/INTERP_KERNELTest/CppUnitTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx index 85192e313..54eea5623 100644 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx +++ b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx index 88b7662b7..580f7daeb 100644 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx +++ b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/HexaTests.hxx b/src/INTERP_KERNELTest/HexaTests.hxx index f5fad8094..05e74bdb3 100644 --- a/src/INTERP_KERNELTest/HexaTests.hxx +++ b/src/INTERP_KERNELTest/HexaTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/InterpKernelTestExport.hxx b/src/INTERP_KERNELTest/InterpKernelTestExport.hxx index c936b224a..fb71b5e04 100644 --- a/src/INTERP_KERNELTest/InterpKernelTestExport.hxx +++ b/src/INTERP_KERNELTest/InterpKernelTestExport.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.cxx b/src/INTERP_KERNELTest/Interpolation3DTest.cxx index 5b6376e06..44e600c08 100644 --- a/src/INTERP_KERNELTest/Interpolation3DTest.cxx +++ b/src/INTERP_KERNELTest/Interpolation3DTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.hxx b/src/INTERP_KERNELTest/Interpolation3DTest.hxx index c76c582c5..4b3a8bb0c 100644 --- a/src/INTERP_KERNELTest/Interpolation3DTest.hxx +++ b/src/INTERP_KERNELTest/Interpolation3DTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx index b053d9058..cc79d6341 100644 --- a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx +++ b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx index 6c4fc8602..27ca2be4b 100644 --- a/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx +++ b/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx index 658975c4a..2b33ee9b5 100644 --- a/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx +++ b/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/InterpolationTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationTestSuite.hxx index 4629e894d..ef39f5913 100644 --- a/src/INTERP_KERNELTest/InterpolationTestSuite.hxx +++ b/src/INTERP_KERNELTest/InterpolationTestSuite.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/src/INTERP_KERNELTest/MEDMeshMaker.cxx index d82c32c3a..83efbb661 100644 --- a/src/INTERP_KERNELTest/MEDMeshMaker.cxx +++ b/src/INTERP_KERNELTest/MEDMeshMaker.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.hxx b/src/INTERP_KERNELTest/MEDMeshMaker.hxx index 1595a9eb9..744587041 100644 --- a/src/INTERP_KERNELTest/MEDMeshMaker.hxx +++ b/src/INTERP_KERNELTest/MEDMeshMaker.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/Makefile.am b/src/INTERP_KERNELTest/Makefile.am index 93dc410d7..0fe0cb8b0 100644 --- a/src/INTERP_KERNELTest/Makefile.am +++ b/src/INTERP_KERNELTest/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.hxx b/src/INTERP_KERNELTest/MeshTestToolkit.hxx index 161d11b1d..6d703e78b 100644 --- a/src/INTERP_KERNELTest/MeshTestToolkit.hxx +++ b/src/INTERP_KERNELTest/MeshTestToolkit.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.txx b/src/INTERP_KERNELTest/MeshTestToolkit.txx index e656cad62..6121329e7 100644 --- a/src/INTERP_KERNELTest/MeshTestToolkit.txx +++ b/src/INTERP_KERNELTest/MeshTestToolkit.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MultiElement2DTests.hxx b/src/INTERP_KERNELTest/MultiElement2DTests.hxx index 566026d67..da6f31da1 100644 --- a/src/INTERP_KERNELTest/MultiElement2DTests.hxx +++ b/src/INTERP_KERNELTest/MultiElement2DTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx b/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx index f3b6732aa..a94b308b8 100644 --- a/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx +++ b/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/MultiElementTetraTests.hxx b/src/INTERP_KERNELTest/MultiElementTetraTests.hxx index 8610e652d..9beef0ad7 100644 --- a/src/INTERP_KERNELTest/MultiElementTetraTests.hxx +++ b/src/INTERP_KERNELTest/MultiElementTetraTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/PerfTest.cxx b/src/INTERP_KERNELTest/PerfTest.cxx index fd139bc9a..bd8fff56b 100644 --- a/src/INTERP_KERNELTest/PerfTest.cxx +++ b/src/INTERP_KERNELTest/PerfTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/PointLocatorTest.cxx b/src/INTERP_KERNELTest/PointLocatorTest.cxx index 0dd2bfa70..cbe75e6c9 100644 --- a/src/INTERP_KERNELTest/PointLocatorTest.cxx +++ b/src/INTERP_KERNELTest/PointLocatorTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/PointLocatorTest.hxx b/src/INTERP_KERNELTest/PointLocatorTest.hxx index d918387ca..2c98b255f 100644 --- a/src/INTERP_KERNELTest/PointLocatorTest.hxx +++ b/src/INTERP_KERNELTest/PointLocatorTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx index 577887c6e..385b7c43d 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx index b9d39e015..1536c90cf 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx index 2781d503f..a5374fc49 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx index 7b22ab2ae..08985ce80 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx index 5ab41b33e..a3f1fcb24 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx index 111b61aa3..23210afa5 100644 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/RemapperTest.cxx b/src/INTERP_KERNELTest/RemapperTest.cxx index 8002c73b3..01c7b4596 100644 --- a/src/INTERP_KERNELTest/RemapperTest.cxx +++ b/src/INTERP_KERNELTest/RemapperTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx index 64e07e045..7fa7edeca 100644 --- a/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx +++ b/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx index 4ac48cd13..17ab87e67 100644 --- a/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx +++ b/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/SingleElementTetraTests.hxx b/src/INTERP_KERNELTest/SingleElementTetraTests.hxx index e419b6b96..460fb5654 100644 --- a/src/INTERP_KERNELTest/SingleElementTetraTests.hxx +++ b/src/INTERP_KERNELTest/SingleElementTetraTests.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TestInterpKernel.cxx b/src/INTERP_KERNELTest/TestInterpKernel.cxx index 6272fd3e7..0e1d7de5d 100644 --- a/src/INTERP_KERNELTest/TestInterpKernel.cxx +++ b/src/INTERP_KERNELTest/TestInterpKernel.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx b/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx index 7573e85cf..916afa3b9 100644 --- a/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx +++ b/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx b/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx index ab1863413..0d57f9424 100644 --- a/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx +++ b/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TestingUtils.hxx b/src/INTERP_KERNELTest/TestingUtils.hxx index 503ca0c11..76ab59274 100644 --- a/src/INTERP_KERNELTest/TestingUtils.hxx +++ b/src/INTERP_KERNELTest/TestingUtils.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx index 2306f12d2..1b7916e34 100644 --- a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx +++ b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx index ab6ec1acf..d020aee07 100644 --- a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx +++ b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleTest.cxx index 3051dcf1e..9aeb1ea68 100644 --- a/src/INTERP_KERNELTest/TransformedTriangleTest.cxx +++ b/src/INTERP_KERNELTest/TransformedTriangleTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleTest.hxx index f9ad93774..9409b72bc 100644 --- a/src/INTERP_KERNELTest/TransformedTriangleTest.hxx +++ b/src/INTERP_KERNELTest/TransformedTriangleTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx index b4511ea1c..75e0c0e8f 100644 --- a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx +++ b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx index a7dd33ca7..d1e132f60 100644 --- a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx +++ b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx index 4a15c5bdb..582174532 100644 --- a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx +++ b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx index c17bfcc30..57b7ef275 100644 --- a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx +++ b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/perf_test.py b/src/INTERP_KERNELTest/perf_test.py index 9efe10d58..375d847ef 100755 --- a/src/INTERP_KERNELTest/perf_test.py +++ b/src/INTERP_KERNELTest/perf_test.py @@ -1,5 +1,5 @@ #! /bin/env python -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/INTERP_KERNELTest/perf_test.sh b/src/INTERP_KERNELTest/perf_test.sh index 4af704131..ee081a99d 100755 --- a/src/INTERP_KERNELTest/perf_test.sh +++ b/src/INTERP_KERNELTest/perf_test.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2007-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/MED/CMakeLists.txt b/src/MED/CMakeLists.txt index e3898153e..ecb611c2d 100644 --- a/src/MED/CMakeLists.txt +++ b/src/MED/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCalculator/CMakeLists.txt b/src/MEDCalculator/CMakeLists.txt index 8b29aca91..0cb6372d1 100644 --- a/src/MEDCalculator/CMakeLists.txt +++ b/src/MEDCalculator/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,10 @@ # Author : Anthony Geay (CEA/DEN) ADD_SUBDIRECTORY(Swig) -ADD_SUBDIRECTORY(Test) + +IF(CPPUNIT_IS_OK) + ADD_SUBDIRECTORY(Test) +ENDIF(CPPUNIT_IS_OK) INCLUDE_DIRECTORIES( ${MED3_INCLUDE_DIRS} diff --git a/src/MEDCalculator/Swig/CMakeLists.txt b/src/MEDCalculator/Swig/CMakeLists.txt index 0ea866771..144b81042 100644 --- a/src/MEDCalculator/Swig/CMakeLists.txt +++ b/src/MEDCalculator/Swig/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -47,9 +47,12 @@ INSTALL(TARGETS medcalculatorspython DESTINATION ${MED_salomelib_LIBS}) SET_SOURCE_FILES_PROPERTIES(MEDCalculator.i PROPERTIES CPLUSPLUS ON) SET_SOURCE_FILES_PROPERTIES(MEDCalculator.i PROPERTIES SWIG_DEFINITIONS "-shadow") +IF(NUMPY_STATUS) + SET(SWIG_MODULE_MEDCalculator_EXTRA_FLAGS -DWITH_NUMPY) +ENDIF(NUMPY_STATUS) SWIG_ADD_MODULE(MEDCalculator python MEDCalculator.i) SWIG_LINK_LIBRARIES(MEDCalculator ${PYTHON_LIBS} medcalculator) -SET_TARGET_PROPERTIES(_MEDCalculator PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS}") +SET_TARGET_PROPERTIES(_MEDCalculator PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${PYTHON_DEFINITIONS}") IF(${MACHINE} STREQUAL WINDOWS) SET_TARGET_PROPERTIES(_MEDCalculator PROPERTIES DEBUG_OUTPUT_NAME _MEDCalculator_d) diff --git a/src/MEDCalculator/Test/CMakeLists.txt b/src/MEDCalculator/Test/CMakeLists.txt index 7f28318b2..6835a1696 100644 --- a/src/MEDCalculator/Test/CMakeLists.txt +++ b/src/MEDCalculator/Test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt index ad1c6fa2b..f25bc2bf9 100644 --- a/src/MEDCoupling/CMakeLists.txt +++ b/src/MEDCoupling/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# Copyright (C) 2012-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,9 @@ # # Author : Anthony Geay (CEA/DEN) -ADD_SUBDIRECTORY(Test) +IF(CPPUNIT_STATUS) + ADD_SUBDIRECTORY(Test) +ENDIF(CPPUNIT_STATUS) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR}/../.. @@ -34,8 +36,11 @@ SET(medcoupling_SOURCES MEDCouplingFieldDouble.cxx MEDCouplingUMesh.cxx MEDCouplingMemArray.cxx + MEDCouplingMemArrayChar.cxx MEDCouplingTimeLabel.cxx MEDCouplingCMesh.cxx + MEDCouplingCurveLinearMesh.cxx + MEDCouplingStructuredMesh.cxx MEDCouplingTimeDiscretization.cxx MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx @@ -68,3 +73,7 @@ INSTALL(TARGETS medcouplingremapper DESTINATION ${MED_salomelib_LIBS}) FILE(GLOB medcoupling_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") FILE(GLOB medcoupling_HEADERS_TXX "${CMAKE_CURRENT_SOURCE_DIR}/*.txx") INSTALL(FILES ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} DESTINATION ${MED_salomeinclude_HEADERS}) + +# To allow usage as SWIG dependencies: +SET(medcoupling_HEADERS_HXX PARENT_SCOPE) +SET(medcoupling_HEADERS_TXX PARENT_SCOPE) diff --git a/src/MEDCoupling/MEDCoupling.hxx b/src/MEDCoupling/MEDCoupling.hxx index 0ca61624b..6a81ac9ab 100644 --- a/src/MEDCoupling/MEDCoupling.hxx +++ b/src/MEDCoupling/MEDCoupling.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx index fc0c0f4e9..dc6383933 100644 --- a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx +++ b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,7 @@ namespace ParaMEDMEM const T& operator*() const { return *_ptr; } operator T *() { return _ptr; } operator const T *() const { return _ptr; } + T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; } private: void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); } void destroyPtr() { if(_ptr) _ptr->decrRef(); } diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 2276b4d28..0895a17cf 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,6 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingCMesh.hxx" -#include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" @@ -34,7 +33,7 @@ MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) { } -MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other) +MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy) { if(deepCopy) { @@ -107,6 +106,18 @@ void MEDCouplingCMesh::updateTime() const updateTimeWith(*_z_array); } +std::size_t MEDCouplingCMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + std::set s; + s.insert(_x_array); s.insert(_y_array); s.insert(_z_array); + s.erase(NULL); + for(std::set::const_iterator it=s.begin();it!=s.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + return MEDCouplingStructuredMesh::getHeapMemorySize()+ret; +} + /*! * This method copyies all tiny strings from other (name and components name). * @throw if other and this have not same mesh type. @@ -116,7 +127,7 @@ void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(I const MEDCouplingCMesh *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingMesh::copyTinyStringsFrom(other); + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); if(_x_array && otherC->_x_array) _x_array->copyStringInfoFrom(*otherC->_x_array); if(_y_array && otherC->_y_array) @@ -307,35 +318,11 @@ void MEDCouplingCMesh::getSplitNodeValues(int *res) const } } -int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitCellValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const -{ - int tmp[3]={i,j,k}; - int tmp2[3]; - int spaceDim=getSpaceDimension(); - getSplitNodeValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - -void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res) +void MEDCouplingCMesh::getNodeGridStructure(int *res) const { - int work=nodeId; - for(int i=spaceDim-1;i>=0;i--) - { - int pos=work/split[i]; - work=work%split[i]; - res[i]=pos; - } + int meshDim=getMeshDimension(); + for(int i=0;igetNbOfElems(); } int MEDCouplingCMesh::getSpaceDimension() const @@ -355,92 +342,6 @@ int MEDCouplingCMesh::getMeshDimension() const return getSpaceDimension(); } -INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const -{ - switch(getMeshDimension()) - { - case 3: - return INTERP_KERNEL::NORM_HEXA8; - case 2: - return INTERP_KERNEL::NORM_QUAD4; - case 1: - return INTERP_KERNEL::NORM_SEG2; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); - } -} - -std::set MEDCouplingCMesh::getAllGeoTypes() const -{ - INTERP_KERNEL::NormalizedCellType ret; - switch(getMeshDimension()) - { - case 3: - ret=INTERP_KERNEL::NORM_HEXA8; - break; - case 2: - ret=INTERP_KERNEL::NORM_QUAD4; - break; - case 1: - ret=INTERP_KERNEL::NORM_SEG2; - break; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !"); - } - std::set ret2; - ret2.insert(ret); - return ret2; -} - -int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=getNumberOfCells(); - int dim=getMeshDimension(); - switch(type) - { - case INTERP_KERNEL::NORM_HEXA8: - if(dim==3) - return ret; - case INTERP_KERNEL::NORM_QUAD4: - if(dim==2) - return ret; - case INTERP_KERNEL::NORM_SEG2: - if(dim==1) - return ret; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); - } - return 0; -} - -void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int spaceDim=getSpaceDimension(); - int tmpCell[3],tmpNode[3]; - getSplitCellValues(tmpCell); - getSplitNodeValues(tmpNode); - int tmp2[3]; - GetPosFromId(cellId,spaceDim,tmpCell,tmp2); - switch(spaceDim) - { - case 1: - conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); - break; - case 2: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); - break; - case 3: - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); - conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); - }; -} - void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) { int tmp[3]; @@ -487,6 +388,17 @@ std::string MEDCouplingCMesh::advancedRepr() const return simpleRepr(); } +/*! + * Returns a DataArrayDouble holding positions of nodes along a given axis. + * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value from [0,1,2]. + * \return const DataArrayDouble * - a pointer to the data array of node coordinates + * referred by \a this mesh. + * \throw If \a i is not one of [0,1,2]. + * + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example". + */ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) { switch(i) @@ -502,6 +414,17 @@ const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_K } } +/*! + * Returns a DataArrayDouble holding positions of nodes along a given axis. + * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value from [0,1,2]. + * \return const DataArrayDouble * - a pointer to the data array of node coordinates + * referred by \a this mesh. + * \throw If \a i is not one of [0,1,2]. + * + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example". + */ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception) { switch(i) @@ -517,6 +440,18 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Excep } } +/*! + * Sets node coordinates along a given axis. For more info on Cartesian meshes, see + * \ref MEDCouplingCMeshPage. + * \param [in] i - an index of axis, a value in range [0,1,2]. + * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th + * axis. It must be an array of one component. + * \throw If \a arr->getNumberOfComponents() != 1. + * \throw If \a i is not one of [0,1,2]. + * + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + */ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) { if(arr) @@ -535,6 +470,21 @@ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTE } } +/*! + * Sets node coordinates along some of the tree axes. This method updates all the + * three node coordinates arrays at once. For more info on Cartesian meshes, see + * \ref MEDCouplingCMeshPage. + * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X + * axis. It must be an array of one component or \c NULL. + * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y + * axis. It must be an array of one component or \c NULL. + * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z + * axis. It must be an array of one component or \c NULL. + * \throw If \a coords*->getNumberOfComponents() != 1. + * + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + */ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) { if(coordsX) @@ -561,107 +511,6 @@ void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArray declareAsNew(); } -/*! - * See MEDCouplingUMesh::getDistributionOfTypes for more information - */ -std::vector MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) -{ - //only one type of cell - std::vector ret(3); - ret[0]=getTypeOfCell(0); - ret[1]=getNumberOfCells(); - ret[2]=0; //ret[3*k+2]==0 because it has no sense here - return ret; -} - -/*! - * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information - */ -DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - if(sz!=3) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); - - int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); - if(code[2]==-1) - { - if(code[1]==nbCells) - return 0; - else - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); - } - else - { - if(code[2]<-1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); - if(code[2]>=(int)idsPerType.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); - return idsPerType[code[2]]->deepCpy(); - } -} - -/*! - * See MEDCouplingUMesh::splitProfilePerType for more information - */ -void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) -{ - int nbCells=getNumberOfCells(); - code.resize(3); - code[0]=(int)getTypeOfCell(0); - code[1]=nbCells; - code[2]=0; - idsInPflPerType.push_back(profile->deepCpy()); - idsPerType.push_back(profile->deepCpy()); -} - -MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) -{ - int spaceDim=getSpaceDimension(); - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim); - DataArrayDouble *coords=getCoordinatesAndOwner(); - ret->setCoords(coords); - coords->decrRef(); - switch(spaceDim) - { - case 1: - fill1DUnstructuredMesh(ret); - break; - case 2: - fill2DUnstructuredMesh(ret); - break; - case 3: - fill3DUnstructuredMesh(ret); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); - }; - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPart(start,end); - um->decrRef(); - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; -} - -DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) -{ - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !"); -} - void MEDCouplingCMesh::getBoundingBox(double *bbox) const { int dim=getSpaceDimension(); @@ -680,12 +529,23 @@ void MEDCouplingCMesh::getBoundingBox(double *bbox) const } } +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this + * mesh.
+ * For 1D cells, the returned field contains lengths.
+ * For 2D cells, the returned field contains areas.
+ * For 3D cells, the returned field contains volumes. + * \param [in] isAbs - a not used parameter. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells + * and one time . The caller is to delete this field using decrRef() as it is no + * more needed. + */ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const { std::string name="MeasureOfMesh_"; name+=getName(); int nbelem=getNumberOfCells(); - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS); + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); field->setName(name.c_str()); DataArrayDouble* array=DataArrayDouble::New(); array->alloc(nbelem,1); @@ -693,6 +553,7 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const field->setArray(array) ; array->decrRef(); field->setMesh(const_cast(this)); + field->synchronizeTimeWithMesh(); int tmp[3]; getSplitCellValues(tmp); int dim=getSpaceDimension(); @@ -721,23 +582,6 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) cons //return 0; } -MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - array->alloc(nbOfCells,3); - double *vals=array->getPointer(); - for(int i=0;isetArray(array); - array->decrRef(); - ret->setMesh(this); - return ret; -} - int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const { int dim=getSpaceDimension(); @@ -773,6 +617,12 @@ void MEDCouplingCMesh::rotate(const double *center, const double *vector, double throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !"); } +/*! + * Translates all nodes of \a this mesh by a given vector. Actually, it adds each + * component of the \a vector to all node coordinates of a corresponding axis. + * \param [in] vector - the translation vector whose size must be not less than \a + * this->getSpaceDimension(). + */ void MEDCouplingCMesh::translate(const double *vector) { if(_x_array) @@ -786,6 +636,12 @@ void MEDCouplingCMesh::translate(const double *vector) _z_array->getPointer(),std::bind2nd(std::plus(),vector[2])); } +/*! + * Applies scaling transformation to all nodes of \a this mesh. + * \param [in] point - coordinates of a scaling center. This array is to be of + * size \a this->getSpaceDimension() at least. + * \param [in] factor - a scale factor. + */ void MEDCouplingCMesh::scale(const double *point, double factor) { for(int i=0;i<3;i++) @@ -810,6 +666,13 @@ MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) return 0; } +/*! + * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh. + * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a + * this->getNumberOfNodes() tuples per \a this->getSpaceDimension() + * components. The caller is to delete this array using decrRef() as it is + * no more needed. + */ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const { DataArrayDouble *ret=DataArrayDouble::New(); @@ -836,6 +699,14 @@ DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const return ret; } +/*! + * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is + * computed by averaging coordinates of cell nodes. + * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a + * this->getNumberOfCells() tuples per \a this->getSpaceDimension() + * components. The caller is to delete this array using decrRef() as it is + * no more needed. + */ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const { DataArrayDouble *ret=DataArrayDouble::New(); @@ -866,98 +737,14 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const return ret; } -void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) { - throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); + return MEDCouplingCMesh::getBarycenterAndOwner(); } -void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c=getCoordsAt(0); - int nbOfCells=c->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(nbOfCells+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(3*nbOfCells,1); - ci[0]=0; - int *cp=conn->getPointer(); - for(int i=0;isetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - -void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const -{ - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(5*n1*n2,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;jsetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); -} - -void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const +void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { - const DataArrayDouble *c1=getCoordsAt(0); - const DataArrayDouble *c2=getCoordsAt(1); - const DataArrayDouble *c3=getCoordsAt(2); - int n1=c1->getNbOfElems()-1; - int n2=c2->getNbOfElems()-1; - int n3=c3->getNbOfElems()-1; - DataArrayInt *connI=DataArrayInt::New(); - connI->alloc(n1*n2*n3+1,1); - int *ci=connI->getPointer(); - DataArrayInt *conn=DataArrayInt::New(); - conn->alloc(9*n1*n2*n3,1); - ci[0]=0; - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;ksetConnectivity(conn,connI,true); - conn->decrRef(); - connI->decrRef(); + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); } void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const @@ -1041,7 +828,85 @@ void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, con void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) { - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !"); + std::ostringstream extent; + DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; } + else + { extent << "0 0 "; } + } + ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n"; + ofs << " \n"; + ofs << " \n" << pointData << std::endl; + ofs << " \n"; + ofs << " \n" << cellData << std::endl; + ofs << " \n"; + ofs << " \n"; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + thisArr[i]->writeVTK(ofs,8,"Array"); + else + { + MEDCouplingAutoRefCountObjectPtr coo=DataArrayDouble::New(); coo->alloc(1,1); + coo->setIJ(0,0,0.); + coo->writeVTK(ofs,8,"Array"); + } + } + ofs << " \n"; + ofs << " \n"; + ofs << " \n"; +} + +void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + std::ostringstream stream2[3]; + bool isDef[3]; + int nbOfCells=1,nbOfNodes=1; + for(int i=0;i<3;i++) + { + isDef[i]=thisArr[i]!=0; + if(isDef[i]) + { + char tmp='X'+i; + stream2[i] << tmp << " positions array "; + if(!thisArr[i]->isAllocated()) + stream2[i] << "set but not allocated."; + else + { + int nbCompo=thisArr[i]->getNumberOfComponents(); + if(nbCompo==1) + { + int nbTuples=thisArr[i]->getNumberOfTuples(); + if(nbTuples<1) + { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; } + else + { + stream2[i] << "(length=" << nbTuples << ")" << ": "; + thisArr[i]->reprQuickOverviewData(stream2[i],200); + if(nbOfCells!=-1) + { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; } + } + } + else + { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; } + } + } + } + if(!isDef[0] && !isDef[1] && !isDef[2]) + { stream << " No arrays set !"; return; } + if(nbOfCells>=0) + { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; } + for(int i=0;i<3;i++) + { + if(isDef[i]) + stream << std::endl << stream2[i].str(); + } + } std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index 39407ebb6..ef768835a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -22,14 +22,14 @@ #define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ #include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" +#include "MEDCouplingStructuredMesh.hxx" namespace ParaMEDMEM { class DataArrayDouble; class MEDCouplingUMesh; - class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingMesh + class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingStructuredMesh { public: static MEDCouplingCMesh *New(); @@ -37,6 +37,7 @@ namespace ParaMEDMEM MEDCouplingMesh *deepCpy() const; MEDCouplingCMesh *clone(bool recDeepCpy) const; void updateTime() const; + std::size_t getHeapMemorySize() const; MEDCouplingMeshType getType() const { return CARTESIAN; } void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); @@ -52,13 +53,6 @@ namespace ParaMEDMEM int getNumberOfNodes() const; int getSpaceDimension() const; int getMeshDimension() const; - int getCellIdFromPos(int i, int j, int k) const; - int getNodeIdFromPos(int i, int j, int k) const; - static void GetPosFromId(int nodeId, int spaceDim, const int *split, int *res); - INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - std::set getAllGeoTypes() const; - int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - void getNodeIdsOfCell(int cellId, std::vector& conn) const; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; @@ -69,17 +63,9 @@ namespace ParaMEDMEM const DataArrayDouble *coordsY=0, const DataArrayDouble *coordsZ=0); // tools - std::vector getDistributionOfTypes() const throw(INTERP_KERNEL::Exception); - DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); - void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); void getBoundingBox(double *bbox) const; MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCouplingFieldDouble *buildOrthogonalField() const; int getCellContainingPoint(const double *pos, double eps) const; void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); @@ -87,19 +73,19 @@ namespace ParaMEDMEM MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; DataArrayDouble *getCoordinatesAndOwner() const; DataArrayDouble *getBarycenterAndOwner() const; + DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const; - void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const; - void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const; //some useful methods void getSplitCellValues(int *res) const; void getSplitNodeValues(int *res) const; + void getNodeGridStructure(int *res) const; //serialisation-unserialization void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); private: MEDCouplingCMesh(); MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy); diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx new file mode 100644 index 000000000..6e93efb12 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx @@ -0,0 +1,917 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "MEDCouplingCurveLinearMesh.hxx" +#include "MEDCouplingPointSet.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include "VolSurfUser.txx" +#include "PointLocatorAlgos.txx" + +#include +#include +#include +#include + +using namespace ParaMEDMEM; + +MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh():_coords(0),_structure(0) +{ +} + +MEDCouplingCurveLinearMesh::MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_structure(other._structure) +{ + if(deepCopy) + { + if((const DataArrayDouble *)other._coords) + _coords=other._coords->deepCpy(); + } + else + _coords=other._coords; +} + +MEDCouplingCurveLinearMesh::~MEDCouplingCurveLinearMesh() +{ +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New() +{ + return new MEDCouplingCurveLinearMesh; +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::New(const char *meshName) +{ + MEDCouplingCurveLinearMesh *ret=new MEDCouplingCurveLinearMesh; + ret->setName(meshName); + return ret; +} + +MEDCouplingMesh *MEDCouplingCurveLinearMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingCurveLinearMesh *MEDCouplingCurveLinearMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingCurveLinearMesh(*this,recDeepCpy); +} + +void MEDCouplingCurveLinearMesh::updateTime() const +{ + if((const DataArrayDouble *)_coords) + updateTimeWith(*_coords); +} + +std::size_t MEDCouplingCurveLinearMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_structure.capacity()*sizeof(int); + if((const DataArrayDouble *)_coords) + ret+=_coords->getHeapMemorySize(); + return MEDCouplingStructuredMesh::getHeapMemorySize()+ret; +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingCurveLinearMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); + if((DataArrayDouble *)_coords && (const DataArrayDouble *)otherC->_coords) + _coords->copyStringInfoFrom(*otherC->_coords); +} + +bool MEDCouplingCurveLinearMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingCurveLinearMesh !"; + return false; + } + if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + std::ostringstream oss; oss.precision(15); + if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) + { + oss << "Only one CurveLinearMesh between the two this and other has its coordinates defined !"; + reason=oss.str(); + return false; + } + if((const DataArrayDouble *)_coords) + { + if(!_coords->isEqualIfNotWhy(*(otherC->_coords),prec,reason)) + { + oss << "Coordinates DataArrayDouble of differ :"; + reason.insert(0,oss.str()); + return false; + } + if(_structure!=otherC->_structure) + { reason="CurveLinearMesh structures differ !"; return false; } + } + return true; +} + +bool MEDCouplingCurveLinearMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(((const DataArrayDouble *)_coords && ((const DataArrayDouble *)otherC->_coords)==0) || (((const DataArrayDouble *)_coords)==0 && (const DataArrayDouble *)otherC->_coords)) + return false; + if((const DataArrayDouble *)_coords) + { + if(!_coords->isEqualWithoutConsideringStr(*(otherC->_coords),prec)) + return false; + if(_structure!=otherC->_structure) + return false; + } + return true; +} + +void MEDCouplingCurveLinearMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalWith : Meshes are not the same !"); +} + +/*! + * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCurveLinearMesh instance too). + * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCurveLinearMesh, 'this' and 'other' are the same ! + */ +void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !"); +} + +void MEDCouplingCurveLinearMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + std::size_t sz=_structure.size(),i=0,nbOfNodes=1; + if(sz<1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : structure should have a lgth of size 1 at least !"); + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,i++) + { + if((*it)<1) + { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : At pos #" << i << " of structure value is " << *it << "should be >= 1 !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + nbOfNodes*=*it; + } + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not set !"); + if(!_coords->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array is not allocated !"); + if(_coords->getNumberOfComponents()<1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkCoherency : the array should have >= 1 components !"); + if(_coords->getNumberOfTuples()!=(int)nbOfNodes) + { + std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::checkCoherency : structure said that number of nodes should be equal to " << nbOfNodes << " but number of tuples in array is equal to " << _coords->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCouplingCurveLinearMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); +} + +void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) +{ + checkCoherency1(eps); +} + +int MEDCouplingCurveLinearMesh::getNumberOfCells() const +{ + checkCoherency(); + std::size_t nbOfCells=1,i=0; + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,i++) + nbOfCells*=(*it)-1; + return (int)nbOfCells; +} + +int MEDCouplingCurveLinearMesh::getNumberOfNodes() const +{ + checkCoherency(); + std::size_t nbOfNodes=1; + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++) + nbOfNodes*=(*it); + return (int)nbOfNodes; +} + +void MEDCouplingCurveLinearMesh::getSplitCellValues(int *res) const +{ + int meshDim=getMeshDimension(); + for(int l=0;lgetNumberOfComponents(); +} + +int MEDCouplingCurveLinearMesh::getMeshDimension() const +{ + return (int)_structure.size(); +} + +void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) +{ + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCoordinatesOfNode : Coordinates not set !"); + int nbOfCompo=_coords->getNumberOfComponents(); + if(nodeId>=0 && nodeId<_coords->getNumberOfTuples()) + coo.insert(coo.end(),_coords->begin()+nodeId*nbOfCompo,_coords->begin()+(nodeId+1)*nbOfCompo); + else + { std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::getCoordinatesOfNode : nodeId has to be in [0," << _coords->getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } +} + +std::string MEDCouplingCurveLinearMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "Curve linear mesh with name : \"" << getName() << "\"\n"; + ret << "Description of mesh : \"" << getDescription() << "\"\n"; + int tmpp1,tmpp2; + double tt=getTime(tmpp1,tmpp2); + ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; + ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; + ret << "The nodal stucture of curve linear mesh is : ["; + std::copy(_structure.begin(),_structure.end(),std::ostream_iterator(ret,",")); ret << "]\n"; + ret << "The coords array is this : "; + if((const DataArrayDouble *)_coords) + _coords->reprZipWithoutNameStream(ret); + else + ret << "no array specified !"; + return ret.str(); +} + +std::string MEDCouplingCurveLinearMesh::advancedRepr() const +{ + return simpleRepr(); +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() throw(INTERP_KERNEL::Exception) +{ + return _coords; +} + +const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const throw(INTERP_KERNEL::Exception) +{ + return _coords; +} + +void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception) +{ + if(coords!=(const DataArrayDouble *)_coords) + { + _coords=const_cast(coords); + if(coords) + coords->incrRef(); + declareAsNew(); + } +} + +void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception) +{ + std::size_t sz=std::distance(gridStructBg,gridStructEnd); + if(sz>=1 && sz<=3) + { + _structure.resize(0); + _structure.insert(_structure.end(),gridStructBg,gridStructEnd); + } + else + { + std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::setNodeGridStructure : size of input nodal grid structure (" << sz << ") should be in 1, 2 or 3 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +std::vector MEDCouplingCurveLinearMesh::getNodeGridStructure() const throw(INTERP_KERNEL::Exception) +{ + return _structure; +} + +void MEDCouplingCurveLinearMesh::getBoundingBox(double *bbox) const +{ + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBoundingBox : Coordinates not set !"); + _coords->getMinMaxPerComponent(bbox); +} + +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureField(bool isAbs) const +{ + checkCoherency(); + int meshDim=getMeshDimension(); + std::string name="MeasureOfMesh_"; name+=getName(); + MEDCouplingAutoRefCountObjectPtr field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + field->setName(name.c_str()); field->setMesh(const_cast(this)); field->synchronizeTimeWithMesh(); + switch(meshDim) + { + case 3: + { getMeasureFieldMeshDim3(isAbs,field); return field.retn(); } + case 2: + { getMeasureFieldMeshDim2(isAbs,field); return field.retn(); } + case 1: + { getMeasureFieldMeshDim1(isAbs,field); return field.retn(); } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureField : mesh dimension must be in [1,2,3] !"); + } +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbnodes=getNumberOfNodes(); + int spaceDim=getSpaceDimension(); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + if(nbnodes==0) + { arr->alloc(0,1); return; } + if(spaceDim==1) + { + arr->alloc(nbnodes-1,1); + std::transform(_coords->begin()+1,_coords->end(),_coords->begin(),arr->getPointer(),std::minus()); + if(isAbs) + arr->abs(); + } + else + { + MEDCouplingAutoRefCountObjectPtr tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim); + std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus()); + MEDCouplingAutoRefCountObjectPtr tmp2=tmp->magnitude(); field->setArray(tmp2); + } +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + arr->alloc(nbcells,1); + double *pt=arr->getPointer(); + const double *coords=_coords->begin(); + int nX=_structure[0]-1; + int conn[4]; + for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coords,spaceDim); + } + if(isAbs) + arr->abs(); +} + +/*! + * \param [in,out] f field feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getMeasureField + */ +void MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); field->setArray(arr); + arr->alloc(nbcells,1); + double *pt=arr->getPointer(); + const double *coords=_coords->begin(); + int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); + int nY1=_structure[0]*_structure[1]; + int conn[8]; + for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coords,3); + } + if(isAbs) + arr->abs(); +} + +/*! + * not implemented yet ! + */ +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::getMeasureFieldOnNode(bool isAbs) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getMeasureFieldOnNode : not implemented yet !"); +} + +MEDCouplingFieldDouble *MEDCouplingCurveLinearMesh::buildOrthogonalField() const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + array->alloc(nbOfCells,3); + double *vals=array->getPointer(); + for(int i=0;isetArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +/// @cond INTERNAL + +namespace ParaMEDMEM +{ + template + class DummyClsMCL + { + public: + static const int MY_SPACEDIM=SPACEDIMM; + static const int MY_MESHDIM=8; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; + // begin + // useless, but for windows compilation ... + const double* getCoordinatesPtr() const { return 0; } + const int* getConnectivityPtr() const { return 0; } + const int* getConnectivityIndexPtr() const { return 0; } + INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; } + // end + }; +} + +/// @endcond + +int MEDCouplingCurveLinearMesh::getCellContainingPoint(const double *pos, double eps) const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + const double *coords=_coords->getConstPointer(); + int nodeId=-1; + _coords->distanceToTuple(pos,pos+spaceDim,nodeId); + if(nodeId<0) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : internal problem 1 !"); + int conn[8]; + int nbOfNodes=getNumberOfNodes(); + if(nbOfNodes==1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : No cells in this !"); + switch(getMeshDimension()) + { + case 1: + if(spaceDim==1) + { + if(nodeId>0) + { + conn[0]=nodeId-1; conn[1]=nodeId; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) + return nodeId-1; + } + if(nodeId >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) + return nodeId; + } + } + case 2: + if(spaceDim==2) + { + int ny=nodeId/_structure[0],nx=nodeId-ny*_structure[0]; + if(nx>0 && ny>0) + { + conn[0]=nx-1+_structure[0]*(ny-1); conn[1]=nx-1+_structure[0]*ny; conn[2]=nx+_structure[0]*ny; conn[3]=nx+_structure[0]*(ny-1); + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx-1+(ny-1)*_structure[0]; + } + if(nx<_structure[0]-1 && ny>0) + { + conn[0]=nx+_structure[0]*(ny-1); conn[1]=nx+_structure[0]*ny; conn[2]=nx+1+_structure[0]*ny; conn[3]=nx+1+_structure[0]*(ny-1); + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx+(ny-1)*_structure[0]; + } + if(nx>0 && ny<_structure[1]-1) + { + conn[0]=nx-1+_structure[0]*ny; conn[1]=nx-1+_structure[0]*(ny+1); conn[2]=nx+_structure[0]*(ny+1); conn[3]=nx+_structure[0]*ny; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx-1+ny*_structure[0]; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1) + { + conn[0]=nx+_structure[0]*ny; conn[1]=nx+_structure[0]*(ny+1); conn[2]=nx+1+_structure[0]*(ny+1); conn[3]=nx+1+_structure[0]*ny; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_QUAD4,coords,conn,4,eps)) + return nx+ny*_structure[0]; + } + } + case 3: + { + if(spaceDim==3) + { + int nY=_structure[0]*_structure[1]; + int nz=nodeId/_structure[1]; int ny=(nodeId-nz*nY)/_structure[0]; int nx=(nodeId-nz*nY)-_structure[0]*ny; + if(nx>0 && ny>0 && nz>0) + { + conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+(ny-1)*_structure[0]+(nz-1)*nY; + } + if(nx<_structure[0]-1 && ny>0 && nz>0) + { + conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+(ny-1)*_structure[0]+(nz-1)*nY; + } + if(nx>0 && ny<_structure[1]-1 && nz>0) + { + conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); + conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+ny*_structure[0]+(nz-1)*nY; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz>0) + { + conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); + conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+ny*_structure[0]+(nz-1)*nY; + } + if(nx>0 && ny>0 && nz<_structure[2]-1) + { + conn[0]=nx-1+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx-1+_structure[2]*ny+nY*(nz-1); conn[2]=nx+_structure[2]*ny+nY*(nz-1); conn[3]=nx+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx-1+_structure[0]*(ny-1)+nY*nz; conn[5]=nx-1+_structure[0]*ny+nY*nz; conn[6]=nx+_structure[0]*ny+nY*nz; conn[7]=nx+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+(ny-1)*_structure[0]+nz*nY; + } + if(nx<_structure[0]-1 && ny>0 && nz<_structure[2]-1) + { + conn[0]=nx+_structure[0]*(ny-1)+nY*(nz-1); conn[1]=nx+_structure[0]*ny+nY*(nz-1); conn[2]=nx+1+_structure[0]*ny+nY*(nz-1); conn[3]=nx+1+_structure[0]*(ny-1)+nY*(nz-1); + conn[4]=nx+_structure[0]*(ny-1)+nY*nz; conn[5]=nx+_structure[0]*ny+nY*nz; conn[6]=nx+1+_structure[0]*ny+nY*nz; conn[7]=nx+1+_structure[0]*(ny-1)+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+(ny-1)*_structure[0]+nz*nY; + } + if(nx>0 && ny<_structure[1]-1 && nz<_structure[2]-1) + { + conn[0]=nx-1+_structure[0]*ny+nY*(nz-1); conn[1]=nx-1+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+_structure[0]*ny+nY*(nz-1); + conn[4]=nx-1+_structure[0]*ny+nY*nz; conn[5]=nx-1+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx-1+ny*_structure[0]+nz*nY; + } + if(nx<_structure[0]-1 && ny<_structure[1]-1 && nz<_structure[2]-1) + { + conn[0]=nx+_structure[0]*ny+nY*(nz-1); conn[1]=nx+_structure[0]*(ny+1)+nY*(nz-1); conn[2]=nx+1+_structure[0]*(ny+1)+nY*(nz-1); conn[3]=nx+1+_structure[0]*ny+nY*(nz-1); + conn[4]=nx+_structure[0]*ny+nY*nz; conn[5]=nx+_structure[0]*(ny+1)+nY*nz; conn[6]=nx+1+_structure[0]*(ny+1)+nY*nz; conn[7]=nx+1+_structure[0]*ny+nY*nz; + if(INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_HEXA8,coords,conn,8,eps)) + return nx+ny*_structure[0]+nz*nY; + } + } + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getCellContainingPoint : mesh dimension managed are 1, 2 or 3 !"); + } +} + +void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vector, double angle) +{ + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : no coordinates set !"); + int spaceDim=getSpaceDimension(); + int nbNodes=_coords->getNumberOfTuples(); + double *coords=_coords->getPointer(); + if(spaceDim==3) + MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords); + else if(spaceDim==2) + MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords); + else + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3"); + _coords->declareAsNew(); + updateTime(); +} + +void MEDCouplingCurveLinearMesh::translate(const double *vector) +{ + if(!vector) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : NULL input point !"); + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !"); + double *coords=_coords->getPointer(); + int nbNodes=getNumberOfNodes(); + int dim=getSpaceDimension(); + for(int i=0; ideclareAsNew(); + updateTime(); +} + +void MEDCouplingCurveLinearMesh::scale(const double *point, double factor) +{ + if(!point) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : NULL input point !"); + if(!((DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !"); + double *coords=_coords->getPointer(); + int nbNodes=_coords->getNumberOfTuples(); + int dim=_coords->getNumberOfComponents(); + for(int i=0;i()); + std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); + } + _coords->declareAsNew(); + updateTime(); +} + +MEDCouplingMesh *MEDCouplingCurveLinearMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::mergeMyselfWith : not available for CurveLinear Mesh !"); +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getCoordinatesAndOwner() const +{ + DataArrayDouble *ret=const_cast((const DataArrayDouble *)_coords); + if(ret) + ret->incrRef(); + return ret; +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + int nbOfCells=getNumberOfCells(); + ret->alloc(nbOfCells,spaceDim); + ret->copyStringInfoFrom(*getCoords()); + switch(meshDim) + { + case 3: + { getBarycenterAndOwnerMeshDim3(ret); return ret.retn(); } + case 2: + { getBarycenterAndOwnerMeshDim2(ret); return ret.retn(); } + case 1: + { getBarycenterAndOwnerMeshDim1(ret); return ret.retn(); } + default: + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwner : mesh dimension must be in [1,2,3] !"); + } +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + return MEDCouplingCurveLinearMesh::getBarycenterAndOwner(); +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const +{ + int nbOfCells=getNumberOfCells(); + double *ptToFill=bary->getPointer(); + const double *coor=_coords->getConstPointer(); + if(getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim3 : with meshDim 3 only space dimension 3 is possible !"); + int nX=_structure[0]-1,nY=(_structure[0]-1)*(_structure[1]-1); + int nY1=_structure[0]*_structure[1]; + int conn[8]; + for(int i=0;i(INTERP_KERNEL::NORM_HEXA8,conn,8,coor,3,ptToFill); + ptToFill+=3; + } +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const +{ + int nbcells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + double *ptToFill=bary->getPointer(); + const double *coor=_coords->getConstPointer(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim2 : with meshDim 2 only space dimension 2 and 3 are possible !"); + int nX=_structure[0]-1; + int conn[4]; + for(int i=0;i(INTERP_KERNEL::NORM_QUAD4,conn,4,coor,spaceDim,ptToFill); + ptToFill+=spaceDim; + } +} + +/*! + * \param [in,out] bary Barycenter array feeded with good values. + * \sa MEDCouplingCurveLinearMesh::getBarycenterAndOwner + */ +void MEDCouplingCurveLinearMesh::getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const +{ + int spaceDim=getSpaceDimension(); + std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),bary->getPointer(),std::plus()); + std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies(),0.5)); +} + +void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !"); +} + +void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const +{ + int it,order; + double time=getTime(it,order); + tinyInfo.clear(); + tinyInfoD.clear(); + littleStrings.clear(); + littleStrings.push_back(getName()); + littleStrings.push_back(getDescription()); + littleStrings.push_back(getTimeUnit()); + // + std::vector littleStrings2; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationStrInformation(littleStrings2); + littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); + // + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfo.push_back((int)_structure.size()); + for(std::vector::const_iterator itt=_structure.begin();itt!=_structure.end();itt++) + tinyInfo.push_back(*itt); + std::vector tinyInfo2; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationIntInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + // + tinyInfoD.push_back(time); +} + +void MEDCouplingCurveLinearMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const +{ + a1->alloc(tinyInfo[2],1); + std::vector tinyInfo2(tinyInfo.begin()+3+tinyInfo[2],tinyInfo.end()); + a2->resizeForUnserialization(tinyInfo2); +} + +void MEDCouplingCurveLinearMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); + a1->alloc((int)_structure.size(),1); + int *ptr=a1->getPointer(); + for(std::vector::const_iterator it=_structure.begin();it!=_structure.end();it++,ptr++) + *ptr=(*it); + int sz=0; + if((const DataArrayDouble *)_coords) + if(_coords->isAllocated()) + sz=_coords->getNbOfElems(); + a2=DataArrayDouble::New(); + a2->alloc(sz,1); + if(sz!=0 && (const DataArrayDouble *)_coords) + std::copy(_coords->begin(),_coords->end(),a2->getPointer()); +} + +void MEDCouplingCurveLinearMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings) +{ + setName(littleStrings[0].c_str()); + setDescription(littleStrings[1].c_str()); + setTimeUnit(littleStrings[2].c_str()); + setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); + int sz=tinyInfo[2]; + _structure.resize(sz); + for(int i=0;isz+3) + { + _coords=DataArrayDouble::New(); + std::vector tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end()); + _coords->resizeForUnserialization(tinyInfo2); + std::copy(a2->begin(),a2->end(),_coords->getPointer()); + std::vector littleStrings2(littleStrings.begin()+3,littleStrings.end()); + _coords->finishUnserialization(tinyInfo2,littleStrings2); + } +} + +void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream extent; + int meshDim=(int)_structure.size(); + if(meshDim<=0 || meshDim>3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::writeVTKLL : meshDim invalid ! must be in [1,2,3] !"); + for(int i=0;i<3;i++) + { int val=i\n"; + ofs << " \n"; + ofs << " \n" << pointData << std::endl; + ofs << " \n"; + ofs << " \n" << cellData << std::endl; + ofs << " \n"; + ofs << " \n"; + if(getSpaceDimension()==3) + _coords->writeVTK(ofs,8,"Points"); + else + { + MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); + coo->writeVTK(ofs,8,"Points"); + } + ofs << " \n"; + ofs << " \n"; + ofs << " \n"; +} + +void MEDCouplingCurveLinearMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCouplingCurveLinearMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; + stream << "Nodal structure : ["; + for(std::size_t i=0;i<_structure.size();i++) + { + char tmp='X'+i; + stream << " " << tmp << "=" << _structure[i]; + if(i!=_structure.size()-1) + stream << ", "; + } + stream << " ]."; + const DataArrayDouble *coo(_coords); + if(!coo) + { stream << std::endl << "No coordinates set !"; return ; } + if(!coo->isAllocated()) + { stream << std::endl << "Coordinates set but not allocated !"; return ; } + int nbOfCompo=coo->getNumberOfComponents(); + if(nbOfCompo!=(int)_structure.size()) + { stream << std::endl << "Coordinates set and allocated but mismatch number of components !"; return ; } + stream << std::endl << "Coordinates ( number of tuples = " << coo->getNumberOfTuples() << " ) : "; + coo->reprQuickOverviewData(stream,200); +} + +std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) +{ + return std::string("StructuredGrid"); +} diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx new file mode 100644 index 000000000..047bac5ce --- /dev/null +++ b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx @@ -0,0 +1,109 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#ifndef __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGCURVELINEARMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingStructuredMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + + class MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh + { + public: + static MEDCouplingCurveLinearMesh *New(); + static MEDCouplingCurveLinearMesh *New(const char *meshName); + MEDCouplingMesh *deepCpy() const; + MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; + void updateTime() const; + std::size_t getHeapMemorySize() const; + MEDCouplingMeshType getType() const { return CURVE_LINEAR; } + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + int getNumberOfCells() const; + int getNumberOfNodes() const; + int getSpaceDimension() const; + int getMeshDimension() const; + void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + std::string advancedRepr() const; + DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception); + const DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception); + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) throw(INTERP_KERNEL::Exception); + std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); + // tools + void getBoundingBox(double *bbox) const; + MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCouplingFieldDouble *buildOrthogonalField() const; + int getCellContainingPoint(const double *pos, double eps) const; + void rotate(const double *center, const double *vector, double angle); + void translate(const double *vector); + void scale(const double *point, double factor); + MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + DataArrayDouble *getCoordinatesAndOwner() const; + DataArrayDouble *getBarycenterAndOwner() const; + DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); + //some useful methods + void getSplitCellValues(int *res) const; + void getSplitNodeValues(int *res) const; + void getNodeGridStructure(int *res) const; + //serialisation-unserialization + void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + private: + void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception); + void getBarycenterAndOwnerMeshDim3(DataArrayDouble *bary) const; + void getBarycenterAndOwnerMeshDim2(DataArrayDouble *bary) const; + void getBarycenterAndOwnerMeshDim1(DataArrayDouble *bary) const; + private: + MEDCouplingCurveLinearMesh(); + MEDCouplingCurveLinearMesh(const MEDCouplingCurveLinearMesh& other, bool deepCpy); + ~MEDCouplingCurveLinearMesh(); + void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception); + std::string getVTKDataSetType() const throw(INTERP_KERNEL::Exception); + private: + MEDCouplingAutoRefCountObjectPtr _coords; + std::vector _structure; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx b/src/MEDCoupling/MEDCouplingDefinitionTime.cxx index 0d703ce73..45aa50c7a 100644 --- a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx +++ b/src/MEDCoupling/MEDCouplingDefinitionTime.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -109,6 +109,11 @@ MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCoupling throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ..."); } +std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySize() const +{ + return 0; +} + bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const { double t1=getStartTime(); @@ -459,6 +464,11 @@ MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector& tiI, std::vector& tiD) const = 0; virtual TypeOfTimeDiscretization getTimeType() const = 0; + std::size_t getHeapMemorySize() const; bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; @@ -142,6 +143,7 @@ namespace ParaMEDMEM public: MEDCouplingDefinitionTime(); MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; void assign(const MEDCouplingDefinitionTime& other); bool isEqual(const MEDCouplingDefinitionTime& other) const; double getTimeResolution() const { return _eps; } diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 663737af5..2e2b03870 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -64,6 +64,18 @@ MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const return EXTRUDED; } +std::size_t MEDCouplingExtrudedMesh::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_mesh2D) + ret+=_mesh2D->getHeapMemorySize(); + if(_mesh1D) + ret+=_mesh1D->getHeapMemorySize(); + if(_mesh3D_ids) + ret+=_mesh3D_ids->getHeapMemorySize(); + return MEDCouplingMesh::getHeapMemorySize()+ret; +} + /*! * This method copyies all tiny strings from other (name and components name). * @throw if other and this have not same mesh type. @@ -240,6 +252,55 @@ std::set MEDCouplingExtrudedMesh::getAllGeoTy return ret; } +DataArrayInt *MEDCouplingExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + INTERP_KERNEL::NormalizedCellType revExtTyp=cm.getReverseExtrudedType(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + if(revExtTyp==INTERP_KERNEL::NORM_ERROR) + { + ret->alloc(0,1); + return ret.retn(); + } + MEDCouplingAutoRefCountObjectPtr tmp=_mesh2D->giveCellsWithType(revExtTyp); + int nbOfLevs=_mesh1D->getNumberOfCells(); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + int nbOfTuples=tmp->getNumberOfTuples(); + ret->alloc(nbOfLevs*nbOfTuples,1); + int *pt=ret->getPointer(); + for(int i=0;ibegin(),tmp->end(),pt,std::bind2nd(std::plus(),i*nbOfCells2D)); + MEDCouplingAutoRefCountObjectPtr ret2=ret->renumberR(_mesh3D_ids->begin()); + ret2->sort(); + return ret2.retn(); +} + +DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret2D=_mesh2D->computeNbOfNodesPerCell(); + int nbOfLevs=_mesh1D->getNumberOfCells(); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); + int *pt=ret3D->getPointer(); + for(int i=0;ibegin(),ret2D->end(),pt); + ret3D->applyLin(2,0,0); + return ret3D->renumberR(_mesh3D_ids->begin()); +} + +DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret2D=_mesh2D->computeNbOfNodesPerCell(); + int nbOfLevs=_mesh1D->getNumberOfCells(); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); + int *pt=ret3D->getPointer(); + for(int i=0;ibegin(),ret2D->end(),pt); + ret3D->applyLin(2,2,0); + return ret3D->renumberR(_mesh3D_ids->begin()); +} + int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const { int ret=0; @@ -398,8 +459,9 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const int nbOf1DCells=_mesh1D->getNumberOfCells(); int nbOf3DCells=nbOf2DCells*nbOf1DCells; const int *renum=_mesh3D_ids->getConstPointer(); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); ret->setMesh(this); + ret->synchronizeTimeWithMesh(); DataArrayDouble *da=DataArrayDouble::New(); da->alloc(nbOf3DCells,1); double *retPtr=da->getPointer(); @@ -686,8 +748,12 @@ DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const { - //not yet implemented - return 0; + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getBarycenterAndOwner : not yet implemented !"); +} + +DataArrayDouble *MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !"); } void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception) @@ -867,6 +933,11 @@ void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& c m->writeVTKLL(ofs,cellData,pointData); } +void MEDCouplingExtrudedMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCouplingExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; +} + std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception) { return _mesh2D->getVTKDataSetType(); diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 9dc8122ed..06a5a871e 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -39,6 +39,7 @@ namespace ParaMEDMEM static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); static MEDCouplingExtrudedMesh *New(); MEDCouplingMeshType getType() const; + std::size_t getHeapMemorySize() const; void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); int getNumberOfCells() const; int getNumberOfNodes() const; @@ -54,6 +55,9 @@ namespace ParaMEDMEM DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; std::set getAllGeoTypes() const; + DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; void getNodeIdsOfCell(int cellId, std::vector& conn) const; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); @@ -90,12 +94,14 @@ namespace ParaMEDMEM MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; DataArrayDouble *getCoordinatesAndOwner() const; DataArrayDouble *getBarycenterAndOwner() const; + DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); //Serialization unserialisation void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); private: MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy); diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 805b4a7c5..e189f32be 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -45,7 +45,7 @@ bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double mes } if(_nature!=other->_nature) { - oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::getRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::getRepr(other->_nature) << "\" !"; + oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !"; reason=oss.str(); return false; } @@ -69,14 +69,36 @@ bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double mes return ret; } +/*! + * Checks if \a this and another MEDCouplingField are fully equal. + * \param [in] other - the field to compare with \a this one. + * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. + * \param [in] valsPrec - precision used to compare field values. + * \return bool - \c true if the two fields are equal, \c false else. + * \throw If \a other is NULL. + */ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const { std::string tmp; return isEqualIfNotWhy(other,meshPrec,valsPrec,tmp); } +/*! + * Checks if \a this and another MEDCouplingField are equal. The textual + * information like names etc. is not considered. + * \param [in] other - the field to compare with \a this one. + * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. + * \param [in] valsPrec - precision used to compare field values. + * \return bool - \c true if the two fields are equal, \c false else. + * \throw If \a other is NULL. + * \throw If the spatial discretization of \a this field is NULL. + */ bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : input field is NULL !"); + if(!_type) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : spatial discretization of this is NULL !"); if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec)) return false; if(_nature!=other->_nature) @@ -97,6 +119,8 @@ bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *othe */ bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : input field is NULL !"); if(!_type->isEqual(other->_type,1.)) return false; if(_nature!=other->_nature) @@ -112,6 +136,8 @@ bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) cons */ bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !"); if(!_type->isEqual(other->_type,1.e-12)) return false; if(_nature!=other->_nature) @@ -127,15 +153,37 @@ void MEDCouplingField::updateTime() const updateTimeWith(*_type); } +std::size_t MEDCouplingField::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_name.capacity(); + ret+=_desc.capacity(); + if(_mesh) + ret+=_mesh->getHeapMemorySize(); + if((const MEDCouplingFieldDiscretization *)_type) + ret+=_type->getHeapMemorySize(); + return ret; +} + +/*! + * Returns a type of \ref MEDCouplingSpatialDisc "spatial discretization" of \a this + * field in terms of enum ParaMEDMEM::TypeOfField. + * \return ParaMEDMEM::TypeOfField - the type of \a this field. + */ TypeOfField MEDCouplingField::getTypeOfField() const { return _type->getEnum(); } /*! - * This method returns the nature of field. This information is very important during interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned before this attribute of the field is not sensitive. This attribute is not store in MED file in MEDLoader. - * More information of the semantic, and the consequence of this attribute in the result of the interpolation, is available \ref NatureOfField "here". + * Returns the nature of \a this field. This information is very important during + * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. + * In other context than the two mentioned above, this attribute is unimportant. This + * attribute is not stored in the MED file. + * For more information of the semantics and the influence of this attribute to the + * result of interpolation, see + * - \ref NatureOfField + * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" */ NatureOfField MEDCouplingField::getNature() const { @@ -143,39 +191,76 @@ NatureOfField MEDCouplingField::getNature() const } /*! - * This method set the nature of field in \b this.This information is very important during interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned before this attribute of the field is not sensitive. This attribute is not store in MED file in MEDLoader. - * More information of the semantic, and the consequence of this attribute in the result of the interpolation, is available \ref TableNatureOfField "here". + * Sets the nature of \a this field. This information is very important during + * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. + * In other context than the two mentioned above, this attribute is unimportant. This + * attribute is not stored in the MED file. + * For more information of the semantics and the influence of this attribute to the + * result of interpolation, see + * - \ref NatureOfField + * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" + * + * \param [in] nat - the nature of \a this field. + * \throw If \a nat has an invalid value. */ void MEDCouplingField::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception) { + MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized _nature=nat; } /*! - * This method returns is case of success an instance of DataArrayDouble the user is in reponsability to deal with. - * If 'this->_mesh' is not set an exception will be thrown. - * For a field on node the array of coords will be returned. For a field on cell a ParaMEDMEM::DataArrayDouble instance - * containing the barycenter of cells will be returned. And for a field on gauss point the explicit position of gauss points. + * Returns coordinates of field location points that depend on + * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field. + * - For a field on nodes, returns coordinates of nodes. + * - For a field on cells, returns barycenters of cells. + * - For a field on gauss points, returns coordinates of gauss points. + * + * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No mesh set !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No spatial discretization set !"); return _type->getLocalizationOfDiscValues(_mesh); } /*! - * This method retrieves the measure field of 'this'. If no '_mesh' is defined an exception will be thrown. - * Warning the retrieved field life cycle is the responsability of caller. + * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh whose + * cells are constructed around field location points (getLocalizationOfDiscr()) of \a this + * field. (In case of a field on cells, the dual mesh coincides with the underlying mesh).
+ * For 1D cells, the returned field contains lengths.
+ * For 2D cells, the returned field contains areas.
+ * For 3D cells, the returned field contains volumes. + * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell + * orientation, i.e. the volume is always positive. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. + * The caller is to delete this array using decrRef() as + * it is no more needed. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the spatial discretization of \a this field is not well defined. */ + MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception) { - if(_mesh==0) - throw INTERP_KERNEL::Exception("MEDCouplingField::getMeasureField : no mesh defined !!!"); + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : No spatial discretization set !"); return _type->getMeasureField(_mesh,isAbs); } +/*! + * Sets the underlying mesh of \a this field. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] mesh - the new underlying mesh. + */ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) { if(mesh!=_mesh) @@ -183,6 +268,7 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) if(_mesh) _mesh->decrRef(); _mesh=mesh; + declareAsNew(); if(_mesh) { _mesh->incrRef(); @@ -192,129 +278,199 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) } /*! - * This method sets gauss localization by geometric type. - * @param type geometric type on which the gauss localization will be set. - * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType - * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType - * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. - * @throw when size of 'RefCoo' is not valid regarding 'type' parameter, it throws too when the mesh is not set before or if it is not a field on Gauss points. + * Sets localization of Gauss points for a given geometric type of cell. + * \param [in] type - the geometric type of cell for which the Gauss localization is set. + * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector + * must be \c nbOfNodesPerCell * \c dimOfType. + * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector + * must be _wg_.size() * \c dimOfType. + * \param [in] wg - the weights of Gauss points. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If size of any vector do not match the \a type. */ void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnType method !"); _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg); } /*! - * This method sets on ids defined by [begin;end) their gauss localization. This method checks the coherency of cells ids in [begin;end) and 'refCoo' size. - * If an incoherence appears an exception will be thrown and no seting will be performed. - * An exception is thrown too if [begin,end) has a size lesser than 1. - * - * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType - * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType - * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. - * @throw when size of 'RefCoo' is not valid regarding cells in [begin,end) parameters, it throws too when the mesh is not set before or if it is not a field on Gauss points. + * Sets localization of Gauss points for given cells specified by their ids. + * \param [in] begin - an array of cell ids of interest. + * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. + * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector + * must be \c nbOfNodesPerCell * \c dimOfType. + * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector + * must be _wg_.size() * \c dimOfType. + * \param [in] wg - the weights of Gauss points. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If size of any vector do not match the type of cell # \a begin[0]. + * \throw If type of any cell in \a begin differs from that of cell # \a begin[0]. + * \throw If the range [_begin_,_end_) is empty. */ void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnCells method !"); _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg); } /*! - * This method resets all Gauss loalizations if any. + * Clears data on Gauss points localization. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ void MEDCouplingField::clearGaussLocalizations() { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling clearGaussLocalizations method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !"); _type->clearGaussLocalizations(); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by - * MEDCouplingField::getNbOfGaussLocalization method. - * Warning this method is not const, so the returned object could be modified without any problem. + * Returns a reference to the Gauss localization object by its id. + * \warning This method is not const, so the returned object can be modified without any + * problem. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \return \ref MEDCouplingGaussLocalization & - the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); return _type->getGaussLocalization(locId); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if several localization ids have been found - * for a type. + * Returns an id of the Gauss localization object corresponding to a given cell type. + * \param [in] type - the cell type of interest. + * \return int - the id of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If no Gauss localization object found for the given cell \a type. + * \throw If more than one Gauss localization object found for the given cell \a type. */ int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneType method !"); return _type->getGaussLocalizationIdOfOneType(type); } +/*! + * Returns ids of Gauss localization objects corresponding to a given cell type. + * \param [in] type - the cell type of interest. + * \return std::set - ids of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + */ std::set MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdsOfOneType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !"); return _type->getGaussLocalizationIdsOfOneType(type); } /*! - * This method returns number of Gauss localization available. Implicitely all ids in [0,getNbOfGaussLocalization()) is a valid Gauss localisation id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) + * Returns number of Gauss localization objects available. Implicitly all ids in + * [0,getNbOfGaussLocalization()) are valid Gauss localization ids. + * \return int - the number of available Gauss localization objects. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ int MEDCouplingField::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getNbOfGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !"); return _type->getNbOfGaussLocalization(); } /*! - * This method returns an id of Gauss localization in [0,getNbOfGaussLocalization()) that corresponds to the localization of the cell specified by its cellId. - * This methods throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) or if at the cell with id 'cellId' in this->_mesh no - * Gauss localization has been set. + * Returns an id of the Gauss localization object corresponding to a type of a given cell. + * \param [in] cellId - an id of the cell of interest. + * \return int - the id of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If no Gauss localization object found for the given cell. */ int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !"); return _type->getGaussLocalizationIdOfOneCell(cellId); } /*! - * This method returns all cellIds that share the same Gauss localization given by 'locId' parameter (in range [0,getNbOfGaussLocalization()) ). - * If no cells fit the Gauss localization given by 'locId' cellIds will be returned empty. - * @param locId input that specifies the id of Gauss localization. - * @param cellIds output parameter, that will contain the result if this method succeds. This parameter is systematically cleared when called. - * @throw if there is no mesh, invalid FieldDescription (different from Gauss) or if locId not in [0,getNbOfGaussLocalization()) + * Returns ids of cells that share the same Gauss localization given by its id. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \param [in,out] cellIds - a vector returning ids of found cells. It is cleared before + * filling in. It remains empty if no cells found. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) { cellIds.clear(); if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !"); _type->getCellIdsHavingGaussLocalization(locId,cellIds); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by - * MEDCouplingField::getNbOfGaussLocalization method. - * Warning this method is const. + * Returns a reference to the Gauss localization object by its id. + * \warning This method is const, so the returned object is not apt for modification. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \return \ref const MEDCouplingGaussLocalization & - the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); return _type->getGaussLocalization(locId); } @@ -332,54 +488,124 @@ MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0), { } -MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), - _mesh(0),_type(other._type->clone()) +MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), + _mesh(0),_type(0) { if(other._mesh) { _mesh=other._mesh; _mesh->incrRef(); } + if(deepCopy) + _type=other._type->clone(); + else + _type=other._type; } /*! - * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh. + * Returns a new MEDCouplingMesh constituted by some cells of the underlying mesh of \a + * this filed, and returns ids of entities (nodes, cells, Gauss points) lying on the + * specified cells. The cells to include to the result mesh are specified by an array of + * cell ids. The new mesh shares the coordinates array with the underlying mesh. + * \param [in] start - an array of cell ids to include to the result mesh. + * \param [in] end - specifies the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \param [out] di - a new instance of DataArrayInt holding the ids of entities (nodes, + * cells, Gauss points). The caller is to delete this array using decrRef() as it + * is no more needed. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \sa buildSubMeshDataRange() */ MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshData method !"); return _type->buildSubMeshData(_mesh,start,end,di); } +/*! + * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingField::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !"); + return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di); +} + /*! * This method returns tuples ids implied by the mesh selection of the cell ids contained in array defined as an interval [start;end). * \return a newly allocated DataArrayInt instance containing tuples ids. */ DataArrayInt *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call computeTupleIdsToSelectFromCellIds method !"); return _type->computeTupleIdsToSelectFromCellIds(_mesh,startCellIds,endCellIds); } /*! - * This method returns number of tuples expected regarding its discretization and its _mesh attribute. - * This method expected a not null _mesh instance. If null, an exception will be thrown. + * Returns number of tuples expected regarding the spatial discretization of \a this + * field and number of entities in the underlying mesh. + * \return int - the number of expected tuples. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ int MEDCouplingField::getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfTuplesExpected method !"); if(_mesh) return _type->getNumberOfTuples(_mesh); else throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpected : Empty mesh !"); } +void MEDCouplingField::setDiscretization(MEDCouplingFieldDiscretization *newDisc) +{ + bool needUpdate=(const MEDCouplingFieldDiscretization *)_type!=newDisc; + _type=newDisc; + if(newDisc) + newDisc->incrRef(); + if(needUpdate) + declareAsNew(); +} + /*! - * This method returns number of mesh placed expected regarding its discretization and its _mesh attribute. - * This method expected a not null _mesh instance. If null, an exception will be thrown. + * Returns number of mesh entities in the underlying mesh of \a this field regarding the + * spatial discretization. + * \return int - the number of mesh entities porting the field values. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ int MEDCouplingField::getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfMeshPlacesExpected method !"); if(_mesh) return _type->getNumberOfMeshPlaces(_mesh); else throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfMeshPlacesExpected : Empty mesh !"); } + +/*! + * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason). + */ +void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception) +{ + if(other) + { + setName(other->_name.c_str()); + setDescription(other->_desc.c_str()); + } +} diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 69e6752ee..ed37178f7 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -50,6 +50,7 @@ namespace ParaMEDMEM virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception); virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + virtual void copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception); void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } void setName(const char *name) { _name=name; } @@ -62,10 +63,11 @@ namespace ParaMEDMEM DataArrayDouble *getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const; const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } MEDCouplingFieldDiscretization *getDiscretization() { return _type; } - void setDiscretization(MEDCouplingFieldDiscretization *newDisc) { _type=newDisc; } + void setDiscretization(MEDCouplingFieldDiscretization *newDisc); int getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception); // Gauss point specific methods @@ -82,9 +84,11 @@ namespace ParaMEDMEM void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; + virtual void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; protected: MEDCouplingField(TypeOfField type); - MEDCouplingField(const MEDCouplingField& other); + MEDCouplingField(const MEDCouplingField& other, bool deepCopy=true); MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature=NoNature); virtual ~MEDCouplingField(); protected: diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 80b9d6a63..bb7587bc3 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,39 @@ const char MEDCouplingFieldDiscretizationKriging::REPR[]="KRIGING"; const TypeOfField MEDCouplingFieldDiscretizationKriging::TYPE=ON_NODES_KR; +// doc is here http://www.code-aster.org/V2/doc/default/fr/man_r/r3/r3.01.01.pdf +const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG2[2]={1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG3[3]={0.5555555555555556,0.5555555555555556,0.8888888888888888}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG4[4]={0.347854845137454,0.347854845137454,0.652145154862546,0.652145154862546}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI3[3]={0.16666666666666666,0.16666666666666666,0.16666666666666666}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI6[6]={0.0549758718227661,0.0549758718227661,0.0549758718227661,0.11169079483905,0.11169079483905,0.11169079483905}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_TRI7[7]={0.062969590272413,0.062969590272413,0.062969590272413,0.066197076394253,0.066197076394253,0.066197076394253,0.1125}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD4[4]={1.,1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_QUAD9[9]={0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_TETRA4[4]={0.041666666666666664,0.041666666666666664,0.041666666666666664,0.041666666666666664}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA6[6]={0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.1714677640603567,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.27434842249657065,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.43895747599451296,0.7023319615912208}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA5[5]={0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG2[2]={-1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG3[3]={-1.,0.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG4[4]={-1.,1.,-0.3333333333333333,0.3333333333333333}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI3[6]={0.,0.,1.,0.,0.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI6[12]={0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_TRI7[14]={0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5,0.3333333333333333,0.3333333333333333}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD4[8]={-1.,-1.,1.,-1.,1.,1.,-1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD8[16]={-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_QUAD9[18]={-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_TETRA4[12]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_TETRA10[30]={0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.5,0.,0.5,0.5,0.,0.5,0.,0.5,0.5,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA6[18]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_PENTA15[45]={-1.,1.,0.,-1.,0.,1.,-1.,0.,0.,1.,1.,0.,1.,0.,1.,1.,0.,0.,-1.,0.5,0.5,-1.,0.,0.5,-1.,0.5,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA8[24]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA20[60]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_HEXA27[81]={-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.,-1.,1.,-1.,-1.,-1.,1.,1.,-1.,1.,1.,1.,1.,-1.,1.,1.,0.,-1.,-1.,1.,0.,-1.,0.,1.,-1.,-1.,0.,-1.,-1.,-1.,0.,1.,-1.,0.,1.,1.,0.,-1.,1.,0.,0.,-1.,1.,1.,0.,1.,0.,1.,1.,-1.,0.,1.,0.,0.,-1.,0.,-1.,0.,1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,0.,1.,0.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA5[15]={1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,-1.,0.,0.,0.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_PYRA13[39]={1.,0.,0.,0.,1.,0.,-1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.5,0.5,0.,-0.5,0.5,0.,-0.5,-0.5,0.,0.5,-0.5,0.,0.5,0.,0.5,0.,0.5,0.5,-0.5,0.,0.5,0.,-0.5,0.5}; + MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) { } @@ -86,7 +120,7 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField } } -TypeOfField MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception) +TypeOfField MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception) { std::string reprCpp(repr); if(reprCpp==MEDCouplingFieldDiscretizationP0::REPR) @@ -113,6 +147,15 @@ bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCoupl return isEqual(other,eps); } +/*! + * This method is an alias of MEDCouplingFieldDiscretization::clone. It is only here for coherency with all the remaining of MEDCoupling. + * \sa MEDCouplingFieldDiscretization::clone. + */ +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::deepCpy() const +{ + return clone(); +} + /*! * For all field discretization excepted GaussPts the [ \a startCellIds, \a endCellIds ) has no impact on the cloned instance. */ @@ -121,6 +164,14 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const return clone(); } +/*! + * For all field discretization excepted GaussPts the slice( \a beginCellId, \a endCellIds, \a stepCellId ) has no impact on the cloned instance. + */ +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + return clone(); +} + /*! * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally. */ @@ -128,6 +179,11 @@ void MEDCouplingFieldDiscretization::updateTime() const { } +std::size_t MEDCouplingFieldDiscretization::getHeapMemorySize() const +{ + return 0; +} + /*! * Computes normL1 of DataArrayDouble instance arr. * @param res output parameter expected to be of size arr->getNumberOfComponents(); @@ -135,7 +191,7 @@ void MEDCouplingFieldDiscretization::updateTime() const */ void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception) { - MEDCouplingFieldDouble *vol=getMeasureField(mesh,true); + MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); int nbOfCompo=arr->getNumberOfComponents(); int nbOfElems=getNumberOfTuples(mesh); std::fill(res,res+nbOfCompo,0.); @@ -150,7 +206,6 @@ void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const D deno+=v; } std::transform(res,res+nbOfCompo,res,std::bind2nd(std::multiplies(),1./deno)); - vol->decrRef(); } /*! @@ -160,7 +215,7 @@ void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const D */ void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception) { - MEDCouplingFieldDouble *vol=getMeasureField(mesh,true); + MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); int nbOfCompo=arr->getNumberOfComponents(); int nbOfElems=getNumberOfTuples(mesh); std::fill(res,res+nbOfCompo,0.); @@ -176,7 +231,6 @@ void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const D } std::transform(res,res+nbOfCompo,res,std::bind2nd(std::multiplies(),1./deno)); std::transform(res,res+nbOfCompo,res,std::ptr_fun(std::sqrt)); - vol->decrRef(); } /*! @@ -186,20 +240,44 @@ void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const D */ void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { - MEDCouplingFieldDouble *vol=getMeasureField(mesh,isWAbs); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : mesh is NULL !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : input array is NULL !"); + MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,isWAbs); int nbOfCompo=arr->getNumberOfComponents(); int nbOfElems=getNumberOfTuples(mesh); + if(nbOfElems!=arr->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretization::integral : field is not correct ! number of tuples in array is " << arr->getNumberOfTuples(); + oss << " whereas number of tuples expected is " << nbOfElems << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } std::fill(res,res+nbOfCompo,0.); const double *arrPtr=arr->getConstPointer(); const double *volPtr=vol->getArray()->getConstPointer(); - double *tmp=new double[nbOfCompo]; + INTERP_KERNEL::AutoPtr tmp=new double[nbOfCompo]; for (int i=0;i(),volPtr[i])); - std::transform(tmp,tmp+nbOfCompo,res,res,std::plus()); + std::transform(arrPtr+i*nbOfCompo,arrPtr+(i+1)*nbOfCompo,(double *)tmp,std::bind2nd(std::multiplies(),volPtr[i])); + std::transform((double *)tmp,(double *)tmp+nbOfCompo,res,res,std::plus()); } - delete [] tmp; - vol->decrRef(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretization::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretization::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretization::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + MEDCouplingAutoRefCountObjectPtr da=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildSubMeshData(mesh,da->begin(),da->end(),di); } void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const @@ -301,10 +379,12 @@ void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const char *msg) { + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr : input array is NULL !"); int oldNbOfElems=arr->getNumberOfTuples(); int nbOfComp=arr->getNumberOfComponents(); int newNbOfTuples=newNbOfEntity; - DataArrayDouble *arrCpy=arr->deepCpy(); + MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); const double *ptSrc=arrCpy->getConstPointer(); arr->reAlloc(newNbOfTuples); double *ptToFill=arr->getPointer(); @@ -325,7 +405,6 @@ void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, cons //if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) if(*std::max_element((double *)tmp,((double *)tmp)+nbOfComp)>eps) { - arrCpy->decrRef(); std::ostringstream oss; oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr << " have been merged and " << msg << " field on them are different !"; @@ -334,13 +413,12 @@ void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, cons } } } - arrCpy->decrRef(); } void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const char *msg) { int nbOfComp=arr->getNumberOfComponents(); - DataArrayDouble *arrCpy=arr->deepCpy(); + MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); const double *ptSrc=arrCpy->getConstPointer(); arr->reAlloc(new2OldSz); double *ptToFill=arr->getPointer(); @@ -349,7 +427,6 @@ void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2O int oldNb=new2OldPtr[i]; std::copy(ptSrc+oldNb*nbOfComp,ptSrc+(oldNb+1)*nbOfComp,ptToFill+i*nbOfComp); } - arrCpy->decrRef(); } MEDCouplingFieldDiscretization::~MEDCouplingFieldDiscretization() @@ -361,6 +438,11 @@ TypeOfField MEDCouplingFieldDiscretizationP0::getEnum() const return TYPE; } +/*! + * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. + * + * \sa MEDCouplingFieldDiscretization::deepCpy. + */ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationP0::clone() const { return new MEDCouplingFieldDiscretizationP0; @@ -378,6 +460,11 @@ const char *MEDCouplingFieldDiscretizationP0::getRepr() const bool MEDCouplingFieldDiscretizationP0::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (P0) is defined."; + return false; + } const MEDCouplingFieldDiscretizationP0 *otherC=dynamic_cast(other); bool ret=otherC!=0; if(!ret) @@ -385,18 +472,24 @@ bool MEDCouplingFieldDiscretizationP0::isEqualIfNotWhy(const MEDCouplingFieldDis return ret; } -int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const +int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuples : NULL input mesh !"); return mesh->getNumberOfCells(); } int MEDCouplingFieldDiscretizationP0::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfMeshPlaces : NULL input mesh !"); return mesh->getNumberOfCells(); } DataArrayInt *MEDCouplingFieldDiscretizationP0::getOffsetArr(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getOffsetArr : NULL input mesh !"); int nbOfTuples=mesh->getNumberOfCells(); DataArrayInt *ret=DataArrayInt::New(); ret->alloc(nbOfTuples+1,1); @@ -404,40 +497,56 @@ DataArrayInt *MEDCouplingFieldDiscretizationP0::getOffsetArr(const MEDCouplingMe return ret; } -void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, +void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::renumberArraysForCell : NULL input mesh !"); const int *array=old2NewBg; if(check) array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) + for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) { if(*it) (*it)->renumberInPlace(array); } if(check) - delete [] array; + free(const_cast(array)); } DataArrayDouble *MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues : NULL input mesh !"); return mesh->getBarycenterAndOwner(); } -void MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest) +void MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); + tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + MEDCouplingAutoRefCountObjectPtr tmp2(tmp->deepCpy()); + cellRestriction=tmp.retn(); + trueTupleRestriction=tmp2.retn(); +} + +void MEDCouplingFieldDiscretizationP0::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { - cellRest=DataArrayInt::New(); - cellRest->alloc((int)std::distance(partBg,partEnd),1); - std::copy(partBg,partEnd,cellRest->getPointer()); + stream << "P0 spatial discretization."; } void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) { } -void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) { + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::checkCoherencyBetween : NULL input mesh or DataArray !"); if(mesh->getNumberOfCells()!=da->getNumberOfTuples()) { std::ostringstream message; @@ -449,11 +558,15 @@ void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMe MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getMeasureField : mesh instance specified is NULL !"); return mesh->getMeasureField(isAbs); } void MEDCouplingFieldDiscretizationP0::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getValueOn : NULL input mesh !"); int id=mesh->getCellContainingPoint(loc,_precision); if(id==-1) throw INTERP_KERNEL::Exception("Specified point is detected outside of mesh : unable to apply P0::getValueOn !"); @@ -471,6 +584,8 @@ void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr, DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getValueOnMulti : NULL input mesh !"); std::vector elts,eltsIndex; mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,elts,eltsIndex); int spaceDim=mesh->getSpaceDimension(); @@ -488,8 +603,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArr oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! "; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -522,44 +636,73 @@ DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellI MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc((int)std::distance(startCellIds,endCellIds),1); std::copy(startCellIds,endCellIds,ret->getPointer()); - ret->incrRef(); return ret; + return ret.retn(); } /*! * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). * @param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh. * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh' + * + * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange */ MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { - MEDCouplingMesh *ret=mesh->buildPart(start,end); - di=DataArrayInt::New(); - di->alloc((int)std::distance(start,end),1); - int *pt=di->getPointer(); - std::copy(start,end,pt); - return ret; + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + MEDCouplingAutoRefCountObjectPtr diSafe=DataArrayInt::New(); + diSafe->alloc((int)std::distance(start,end),1); + std::copy(start,end,diSafe->getPointer()); + di=diSafe.retn(); + return ret.retn(); } -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationP0::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationP0::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshDataRange : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + di=0; beginOut=beginCellIds; endOut=endCellIds; stepOut=stepCellIds; + return ret.retn(); +} + +int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfTuples : NULL input mesh !"); return mesh->getNumberOfNodes(); } int MEDCouplingFieldDiscretizationOnNodes::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfMeshPlaces : NULL input mesh !"); return mesh->getNumberOfNodes(); } /*! * Nothing to do here. */ -void MEDCouplingFieldDiscretizationOnNodes::renumberArraysForCell(const MEDCouplingMesh *, const std::vector& arrays, +void MEDCouplingFieldDiscretizationOnNodes::renumberArraysForCell(const MEDCouplingMesh *, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { } DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::getOffsetArr(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getOffsetArr : NULL input mesh !"); int nbOfTuples=mesh->getNumberOfNodes(); DataArrayInt *ret=DataArrayInt::New(); ret->alloc(nbOfTuples+1,1); @@ -569,17 +712,30 @@ DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::getOffsetArr(const MEDCoupl DataArrayDouble *MEDCouplingFieldDiscretizationOnNodes::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getLocalizationOfDiscValues : NULL input mesh !"); return mesh->getCoordinatesAndOwner(); } -void MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest) +void MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception) { - cellRest=mesh->getCellIdsFullyIncludedInNodeIds(partBg,partEnd); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr ret1=mesh->getCellIdsFullyIncludedInNodeIds(tupleIdsBg,tupleIdsEnd); + const MEDCouplingUMesh *meshc=dynamic_cast(mesh); + if(!meshc) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds : trying to subpart field on nodes by node ids ! Your mesh has to be unstructured !"); + MEDCouplingAutoRefCountObjectPtr meshPart=static_cast(meshc->buildPartOfMySelf(ret1->begin(),ret1->end(),true)); + MEDCouplingAutoRefCountObjectPtr ret2=meshPart->computeFetchedNodeIds(); + cellRestriction=ret1.retn(); + trueTupleRestriction=ret2.retn(); } -void MEDCouplingFieldDiscretizationOnNodes::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDiscretizationOnNodes::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) { + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::checkCoherencyBetween : NULL input mesh or DataArray !"); if(mesh->getNumberOfNodes()!=da->getNumberOfTuples()) { std::ostringstream message; @@ -596,11 +752,39 @@ void MEDCouplingFieldDiscretizationOnNodes::checkCoherencyBetween(const MEDCoupl */ MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { - MEDCouplingMesh *ret=mesh->buildPartAndReduceNodes(start,end,di); - DataArrayInt *di2=di->invertArrayO2N2N2O(ret->getNumberOfNodes()); - di->decrRef(); - di=di2; - return ret; + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::buildSubMeshData : NULL input mesh !"); + DataArrayInt *diTmp=0; + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartAndReduceNodes(start,end,diTmp); + MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di=di2.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationNodes::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationNodes::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::buildSubMeshDataRange : NULL input mesh !"); + DataArrayInt *diTmp=0; + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,diTmp); + if(diTmp) + { + MEDCouplingAutoRefCountObjectPtr diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di=di2.retn(); + } + return ret.retn(); } /*! @@ -614,7 +798,7 @@ MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const M DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const { if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::computeTupleIdsToSelectFromCellIds : null mesh !"); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::computeTupleIdsToSelectFromCellIds : NULL input mesh !"); const MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured(); MEDCouplingAutoRefCountObjectPtr umesh2=static_cast(umesh->buildPartOfMySelf(startCellIds,endCellIds,true)); return umesh2->computeFetchedNodeIds(); @@ -653,6 +837,11 @@ TypeOfField MEDCouplingFieldDiscretizationP1::getEnum() const return TYPE; } +/*! + * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. + * + * \sa MEDCouplingFieldDiscretization::deepCpy. + */ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationP1::clone() const { return new MEDCouplingFieldDiscretizationP1; @@ -670,6 +859,11 @@ const char *MEDCouplingFieldDiscretizationP1::getRepr() const bool MEDCouplingFieldDiscretizationP1::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (P1) is defined."; + return false; + } const MEDCouplingFieldDiscretizationP1 *otherC=dynamic_cast(other); bool ret=otherC!=0; if(!ret) @@ -685,11 +879,15 @@ void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfFiel MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getMeasureField : mesh instance specified is NULL !"); return mesh->getMeasureFieldOnNode(isAbs); } void MEDCouplingFieldDiscretizationP1::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueOn : NULL input mesh !"); int id=mesh->getCellContainingPoint(loc,_precision); if(id==-1) throw INTERP_KERNEL::Exception("Specified point is detected outside of mesh : unable to apply P1::getValueOn !"); @@ -705,6 +903,8 @@ void MEDCouplingFieldDiscretizationP1::getValueOn(const DataArrayDouble *arr, co */ void MEDCouplingFieldDiscretizationP1::getValueInCell(const MEDCouplingMesh *mesh, int cellId, const DataArrayDouble *arr, const double *loc, double *res) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueInCell : NULL input mesh !"); std::vector conn; std::vector coo; mesh->getNodeIdsOfCell(cellId,conn); @@ -730,6 +930,8 @@ void MEDCouplingFieldDiscretizationP1::getValueInCell(const MEDCouplingMesh *mes DataArrayDouble *MEDCouplingFieldDiscretizationP1::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::getValueOnMulti : NULL input mesh !"); std::vector elts,eltsIndex; mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,elts,eltsIndex); int spaceDim=mesh->getSpaceDimension(); @@ -747,8 +949,12 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP1::getValueOnMulti(const DataArr oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! "; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - ret->incrRef(); - return ret; + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationP1::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "P1 spatial discretization."; } MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) @@ -761,6 +967,9 @@ MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell() _discr_per_cell->decrRef(); } +/*! + * This constructor deep copies ParaMEDMEM::DataArrayInt instance from other (if any). + */ MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds):_discr_per_cell(0) { DataArrayInt *arr=other._discr_per_cell; @@ -773,16 +982,35 @@ MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(con } } +MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds):_discr_per_cell(0) +{ + DataArrayInt *arr=other._discr_per_cell; + if(arr) + { + _discr_per_cell=arr->selectByTupleId2(beginCellIds,endCellIds,stepCellIds); + } +} + void MEDCouplingFieldDiscretizationPerCell::updateTime() const { if(_discr_per_cell) updateTimeWith(*_discr_per_cell); } -void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_discr_per_cell) + ret+=_discr_per_cell->getHeapMemorySize(); + return ret; +} + +void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) { if(!_discr_per_cell) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has no discretization per cell !"); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween : NULL input mesh or DataArray !"); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); if(nbOfTuples!=mesh->getNumberOfCells()) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has a discretization per cell but it's not matching the underlying mesh !"); @@ -790,10 +1018,15 @@ void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCoupl bool MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (PerCell) is defined."; + return false; + } const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); if(!otherC) { - reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; + reason="Spatial discretization of this is ON_GAUSS, which is not the case of other."; return false; } if(_discr_per_cell==0) @@ -834,15 +1067,17 @@ void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, _discr_per_cell=dpc; // if(check) - delete [] const_cast(array); + free(const_cast(array)); } -void MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m) +void MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary : NULL input mesh !"); if(!_discr_per_cell) { _discr_per_cell=DataArrayInt::New(); - int nbTuples=m->getNumberOfCells(); + int nbTuples=mesh->getNumberOfCells(); _discr_per_cell->alloc(nbTuples,1); int *ptr=_discr_per_cell->getPointer(); std::fill(ptr,ptr+nbTuples,DFT_INVALID_LOCID_VALUE); @@ -858,11 +1093,41 @@ void MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells() const throw(INT throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells : presence of orphan cells !"); } +/*! + * This method is useful when 'this' describes a field discretization with several gauss discretization on a \b same cell type. + * For example same NORM_TRI3 cells having 6 gauss points and others with 12 gauss points. + * This method returns 2 arrays with same size : the return value and 'locIds' output parameter. + * For a given i into [0,locIds.size) ret[i] represents the set of cell ids of i_th set an locIds[i] represents the set of discretisation of the set. + * The return vector contains a set of newly created instance to deal with. + * The returned vector represents a \b partition of cells ids with a gauss discretization set. + * + * If no descretization is set in 'this' and exception will be thrown. + */ +std::vector MEDCouplingFieldDiscretizationPerCell::splitIntoSingleGaussDicrPerCellType(std::vector& locIds) const throw(INTERP_KERNEL::Exception) +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::splitIntoSingleGaussDicrPerCellType : no descretization set !"); + return _discr_per_cell->partitionByDifferentValues(locIds); +} + const DataArrayInt *MEDCouplingFieldDiscretizationPerCell::getArrayOfDiscIds() const { return _discr_per_cell; } +void MEDCouplingFieldDiscretizationPerCell::setArrayOfDiscIds(const DataArrayInt *adids) throw(INTERP_KERNEL::Exception) +{ + if(adids!=_discr_per_cell) + { + if(_discr_per_cell) + _discr_per_cell->decrRef(); + _discr_per_cell=const_cast(adids); + if(_discr_per_cell) + _discr_per_cell->incrRef(); + declareAsNew(); + } +} + MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss() { } @@ -871,6 +1136,10 @@ MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const M { } +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds):MEDCouplingFieldDiscretizationPerCell(other,beginCellIds,endCellIds,stepCellIds),_loc(other._loc) +{ +} + TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const { return TYPE; @@ -878,6 +1147,11 @@ TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const bool MEDCouplingFieldDiscretizationGauss::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (Gauss) is defined."; + return false; + } const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); if(!otherC) { @@ -918,6 +1192,11 @@ bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MED return true; } +/*! + * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. + * + * \sa MEDCouplingFieldDiscretization::deepCpy. + */ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clone() const { return new MEDCouplingFieldDiscretizationGauss(*this); @@ -928,6 +1207,11 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(c return new MEDCouplingFieldDiscretizationGauss(*this,startCellIds,endCellIds); } +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + return new MEDCouplingFieldDiscretizationGauss(*this,beginCellIds,endCellIds,stepCellIds); +} + std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const { std::ostringstream oss; oss << REPR << "." << std::endl; @@ -951,14 +1235,24 @@ std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const return oss.str(); } +std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySize() const +{ + std::size_t ret=_loc.capacity()*sizeof(MEDCouplingGaussLocalization); + for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++) + ret+=(*it).getHeapMemorySize(); + return MEDCouplingFieldDiscretizationPerCell::getHeapMemorySize()+ret; +} + const char *MEDCouplingFieldDiscretizationGauss::getRepr() const { return REPR; } -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const +int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const throw(INTERP_KERNEL::Exception) { int ret=0; + if (_discr_per_cell == 0) + throw INTERP_KERNEL::Exception("Discretization is not initialized!"); const int *dcPtr=_discr_per_cell->getConstPointer(); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) @@ -968,11 +1262,19 @@ int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh int MEDCouplingFieldDiscretizationGauss::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfMeshPlaces : NULL input mesh !"); return mesh->getNumberOfCells(); } +/*! + * This method is redevelopped for performance reasons, but it is equivalent to a call to MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField + * and a call to DataArrayDouble::computeOffsets2 on the returned array. + */ DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : NULL input mesh !"); int nbOfTuples=mesh->getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples+1,1); @@ -992,13 +1294,14 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplin throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } -void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, +void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::renumberArraysForCell : NULL input mesh !"); const int *array=old2NewBg; if(check) array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); @@ -1018,20 +1321,22 @@ void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplin array2[j]=array3[array[i]]+k; } delete [] array3; - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) + for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) if(*it) (*it)->renumberInPlace(array2); delete [] array2; if(check) - delete [] const_cast(array); + free(const_cast(array)); } DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues : NULL input mesh !"); checkNoOrphanCells(); MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured();//in general do nothing int nbOfTuples=getNumberOfTuples(mesh); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int spaceDim=mesh->getSpaceDimension(); ret->alloc(nbOfTuples,spaceDim); std::vector< int > locIds; @@ -1061,13 +1366,21 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValue calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w])); } ret->copyStringInfoFrom(*umesh->getCoords()); - return ret; + return ret.retn(); } -void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest) +void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception) { - throw INTERP_KERNEL::Exception("Not implemented yet !"); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + tmp->sort(true); + tmp=tmp->buildUnique(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=buildNbOfGaussPointPerCellField(); + nbOfNodesPerCell->computeOffsets2(); + nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); } /*! @@ -1147,8 +1460,10 @@ double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, return da->getIJ(offset+nodeIdInCell,compoId); } -void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) { + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween : NULL input mesh or DataArray !"); MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(mesh,da); for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) (*iter).checkCoherency(); @@ -1183,7 +1498,52 @@ void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplin MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { - throw INTERP_KERNEL::Exception("Not implemented yet !"); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : mesh instance specified is NULL !"); + MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isAbs); + const double *volPtr=vol->getArray()->begin(); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_GAUSS_PT); + ret->setMesh(mesh); + ret->setDiscretization(const_cast(this)); + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array not defined ! spatial localization is incorrect !"); + _discr_per_cell->checkAllocated(); + if(_discr_per_cell->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array defined but with nb of components different from 1 !"); + if(_discr_per_cell->getNumberOfTuples()!=vol->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : no discr per cell array defined but mismatch between nb of cells of mesh and size of spatial disr array !"); + MEDCouplingAutoRefCountObjectPtr offset=getOffsetArr(mesh); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); arr->alloc(getNumberOfTuples(mesh),1); + ret->setArray(arr); + double *arrPtr=arr->getPointer(); + const int *offsetPtr=offset->getConstPointer(); + int maxGaussLoc=(int)_loc.size(); + std::vector locIds; + std::vector ids=splitIntoSingleGaussDicrPerCellType(locIds); + std::vector< MEDCouplingAutoRefCountObjectPtr > ids2(ids.size()); std::copy(ids.begin(),ids.end(),ids2.begin()); + for(std::size_t i=0;i=0 && locId weights=new double[nbOfGaussPt]; + double sum=std::accumulate(loc.getWeights().begin(),loc.getWeights().end(),0.); + std::transform(loc.getWeights().begin(),loc.getWeights().end(),(double *)weights,std::bind2nd(std::multiplies(),1./sum)); + for(const int *cellId=curIds->begin();cellId!=curIds->end();cellId++) + for(int j=0;jgetIJ(0,0) << " ! Must be in [0," << maxGaussLoc << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->synchronizeTimeWithSupport(); + return ret.retn(); } void MEDCouplingFieldDiscretizationGauss::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const @@ -1203,8 +1563,58 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getValueOnMulti(const Data MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { - di=computeTupleIdsToSelectFromCellIds(mesh,start,end); - return mesh->buildPart(start,end); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range + return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : NULL input mesh !"); + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : no discretization array set !"); + di=0; beginOut=0; endOut=0; stepOut=stepCellIds; + const char msg[]="MEDCouplingFieldDiscretizationGauss::buildSubMeshDataRange : cell #"; + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + const int *w=_discr_per_cell->begin(); + int nbMaxOfLocId=(int)_loc.size(); + for(int i=0;i=0 && *w=endCellIds) + break; + } + else + { std::ostringstream oss; oss << msg << i << " has invalid id (" << *w << ") ! Should be in [0," << nbMaxOfLocId << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + } + else + { std::ostringstream oss; oss << msg << i << " is detected as orphan !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + } + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + return ret.retn(); } /*! @@ -1218,20 +1628,10 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCe { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : null mesh !"); - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : null discretization ids !"); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=buildNbOfGaussPointPerCellField();//check of _discr_per_cell not NULL pointer int nbOfCells=mesh->getNumberOfCells(); if(_discr_per_cell->getNumberOfTuples()!=nbOfCells) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : mismatch of nb of tuples of cell ids array and number of cells !"); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=DataArrayInt::New(); nbOfNodesPerCell->alloc(nbOfCells,1); - int *retPtr=nbOfNodesPerCell->getPointer(); - const int *pt=_discr_per_cell->getConstPointer(); - int nbMaxOfLocId=(int)_loc.size(); - for(int i=0;i=0 && *ptcomputeOffsets2(); MEDCouplingAutoRefCountObjectPtr sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); return sel->buildExplicitArrByRanges(nbOfNodesPerCell); @@ -1254,41 +1654,45 @@ void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCellsR(const MEDCoupli throw INTERP_KERNEL::Exception("Number of cells has changed and becomes higher with some cells that have been split ! Unable to conserve the Gauss field !"); } -void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, +void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType : NULL input mesh !"); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if((int)cm.getDimension()!=m->getMeshDimension()) + if((int)cm.getDimension()!=mesh->getMeshDimension()) { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType : mismatch of dimensions ! MeshDim==" << m->getMeshDimension(); + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType : mismatch of dimensions ! MeshDim==" << mesh->getMeshDimension(); oss << " whereas Type '" << cm.getRepr() << "' has dimension " << cm.getDimension() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - buildDiscrPerCellIfNecessary(m); + buildDiscrPerCellIfNecessary(mesh); int id=(int)_loc.size(); MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); _loc.push_back(elt); int *ptr=_discr_per_cell->getPointer(); - int nbCells=m->getNumberOfCells(); + int nbCells=mesh->getNumberOfCells(); for(int i=0;igetTypeOfCell(i)==type) + if(mesh->getTypeOfCell(i)==type) ptr[i]=id; zipGaussLocalizations(); } -void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, +void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) { - buildDiscrPerCellIfNecessary(m); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells : NULL input mesh !"); + buildDiscrPerCellIfNecessary(mesh); if(std::distance(begin,end)<1) throw INTERP_KERNEL::Exception("Size of [begin,end) must be equal or greater than 1 !"); - INTERP_KERNEL::NormalizedCellType type=m->getTypeOfCell(*begin); + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(*begin); MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); int id=(int)_loc.size(); int *ptr=_discr_per_cell->getPointer(); for(const int *w=begin+1;w!=end;w++) { - if(m->getTypeOfCell(*w)!=type) + if(mesh->getTypeOfCell(*w)!=type) { std::ostringstream oss; oss << "The cell with id " << *w << " has been detected to be incompatible in the [begin,end) array specified !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); @@ -1312,6 +1716,25 @@ void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() throw(INTERP _loc.clear(); } +void MEDCouplingFieldDiscretizationGauss::setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc) throw(INTERP_KERNEL::Exception) +{ + if(locId<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::setGaussLocalization : localization id has to be >=0 !"); + int sz=(int)_loc.size(); + MEDCouplingGaussLocalization gLoc(INTERP_KERNEL::NORM_ERROR); + if(locId>=sz) + _loc.resize(locId+1,gLoc); + _loc[locId]=loc; +} + +void MEDCouplingFieldDiscretizationGauss::resizeLocalizationVector(int newSz) throw(INTERP_KERNEL::Exception) +{ + if(newSz<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::resizeLocalizationVector : new size has to be >=0 !"); + MEDCouplingGaussLocalization gLoc(INTERP_KERNEL::NORM_ERROR); + _loc.resize(newSz,gLoc); +} + MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) { checkLocalizationId(locId); @@ -1327,7 +1750,7 @@ int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cel { if(!_discr_per_cell) throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - int locId=_discr_per_cell->getConstPointer()[cellId]; + int locId=_discr_per_cell->begin()[cellId]; if(locId<0) throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); return locId; @@ -1399,26 +1822,42 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellFie throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : no discretization array set !"); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - const int *w=_discr_per_cell->getConstPointer(); + const int *w=_discr_per_cell->begin(); ret->alloc(nbOfTuples,1); int *valsToFill=ret->getPointer(); + int nbMaxOfLocId=(int)_loc.size(); for(int i=0;i=0 && *wincrRef(); - return ret; + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : cell #" << i << " is detected as orphan !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationGauss::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Gauss points spatial discretization."; } /*! * This method makes the assumption that _discr_per_cell is set. * This method reduces as much as possible number size of _loc. - * This method is usefull when several set on same cells has been done and that some Gauss Localization are no more used. + * This method is useful when several set on same cells has been done and that some Gauss Localization are no more used. */ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() { - const int *start=_discr_per_cell->getConstPointer(); + const int *start=_discr_per_cell->begin(); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); INTERP_KERNEL::AutoPtr tmp=new int[_loc.size()]; std::fill((int *)tmp,(int *)tmp+_loc.size(),-2); @@ -1443,23 +1882,6 @@ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() _loc=tmpLoc; } -/*! - * This method is usefull when 'this' describes a field discretization with several gauss discretization on a \b same cell type. - * For example same NORM_TRI3 cells having 6 gauss points and others with 12 gauss points. - * This method returns 2 arrays with same size : the return value and 'locIds' output parameter. - * For a given i into [0,locIds.size) ret[i] represents the set of cell ids of i_th set an locIds[i] represents the set of discretisation of the set. - * The return vector contains a set of newly created instance to deal with. - * The returned vector represents a \b partition of cells ids with a gauss discretization set. - * - * If no descretization is set in 'this' and exception will be thrown. - */ -std::vector MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType(std::vector& locIds) const throw(INTERP_KERNEL::Exception) -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType : no descretization set !"); - return _discr_per_cell->partitionByDifferentValues(locIds); -} - MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() { } @@ -1469,6 +1891,11 @@ TypeOfField MEDCouplingFieldDiscretizationGaussNE::getEnum() const return TYPE; } +/*! + * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. + * + * \sa MEDCouplingFieldDiscretization::deepCpy. + */ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGaussNE::clone() const { return new MEDCouplingFieldDiscretizationGaussNE(*this); @@ -1486,6 +1913,11 @@ const char *MEDCouplingFieldDiscretizationGaussNE::getRepr() const bool MEDCouplingFieldDiscretizationGaussNE::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (GaussNE) is defined."; + return false; + } const MEDCouplingFieldDiscretizationGaussNE *otherC=dynamic_cast(other); bool ret=otherC!=0; if(!ret) @@ -1493,8 +1925,10 @@ bool MEDCouplingFieldDiscretizationGaussNE::isEqualIfNotWhy(const MEDCouplingFie return ret; } -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples : NULL input mesh !"); int ret=0; int nbOfCells=mesh->getNumberOfCells(); for(int i=0;igetNumberOfCells(); } DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::getOffsetArr(const MEDCouplingMesh *mesh) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getOffsetArr : NULL input mesh !"); int nbOfTuples=mesh->getNumberOfCells(); DataArrayInt *ret=DataArrayInt::New(); ret->alloc(nbOfTuples+1,1); @@ -1531,9 +1969,11 @@ DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::getOffsetArr(const MEDCoupl return ret; } -void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, +void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell : NULL input mesh !"); const int *array=old2NewBg; if(check) array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); @@ -1557,23 +1997,197 @@ void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCoupl array2[j]=array3[array[i]]+k; } delete [] array3; - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) + for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) if(*it) (*it)->renumberInPlace(array2); delete [] array2; if(check) - delete [] const_cast(array); + free(const_cast(array)); } DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const { - throw INTERP_KERNEL::Exception("Not implemented yet !"); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured();//in general do nothing + int nbOfTuples=getNumberOfTuples(umesh); + int spaceDim=mesh->getSpaceDimension(); + ret->alloc(nbOfTuples,spaceDim); + const double *coords=umesh->getCoords()->begin(); + const int *connI=umesh->getNodalConnectivityIndex()->getConstPointer(); + const int *conn=umesh->getNodalConnectivity()->getConstPointer(); + int nbCells=umesh->getNumberOfCells(); + double *retPtr=ret->getPointer(); + for(int i=0;i=0) + retPtr=std::copy(coords+(*w)*spaceDim,coords+((*w)+1)*spaceDim,retPtr); + return ret.retn(); } -void MEDCouplingFieldDiscretizationGaussNE::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest) +/*! + * Reimplemented from MEDCouplingFieldDiscretization::integral for performance reason. The default implementation is valid too for GAUSS_NE spatial discretization. + */ +void MEDCouplingFieldDiscretizationGaussNE::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { - throw INTERP_KERNEL::Exception("Not implemented yet !"); + if(!mesh || !arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::integral : input mesh or array is null !"); + int nbOfCompo=arr->getNumberOfComponents(); + std::fill(res,res+nbOfCompo,0.); + // + MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isWAbs); + std::set types=mesh->getAllGeoTypes(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + nbOfNodesPerCell->computeOffsets2(); + const double *arrPtr=arr->begin(),*volPtr=vol->getArray()->begin(); + for(std::set::const_iterator it=types.begin();it!=types.end();it++) + { + std::size_t wArrSz=-1; + const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); + INTERP_KERNEL::AutoPtr wArr2=new double[wArrSz]; + double sum=std::accumulate(wArr,wArr+wArrSz,0.); + std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies(),1./sum)); + MEDCouplingAutoRefCountObjectPtr ids=mesh->giveCellsWithType(*it); + MEDCouplingAutoRefCountObjectPtr ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); + const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); + int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); + for(int i=0;i tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + tmp->sort(true); + tmp=tmp->buildUnique(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + nbOfNodesPerCell->computeOffsets2(); + nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); } void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) @@ -1583,6 +2197,8 @@ void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureO double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception) { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getIJK : NULL input mesh !"); int offset=0; for(int i=0;igetIJ(offset+nodeIdInCell,compoId); } -void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) { int nbOfTuples=getNumberOfTuples(mesh); if(nbOfTuples!=da->getNumberOfTuples()) @@ -1605,7 +2221,37 @@ void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCoupl MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { - throw INTERP_KERNEL::Exception("Not implemented yet !"); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !"); + MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isAbs); + const double *volPtr=vol->getArray()->begin(); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_GAUSS_NE); + ret->setMesh(mesh); + // + std::set types=mesh->getAllGeoTypes(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + int nbTuples=nbOfNodesPerCell->accumulate(0); + nbOfNodesPerCell->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); arr->alloc(nbTuples,1); + ret->setArray(arr); + double *arrPtr=arr->getPointer(); + for(std::set::const_iterator it=types.begin();it!=types.end();it++) + { + std::size_t wArrSz=-1; + const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); + INTERP_KERNEL::AutoPtr wArr2=new double[wArrSz]; + double sum=std::accumulate(wArr,wArr+wArrSz,0.); + std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies(),1./sum)); + MEDCouplingAutoRefCountObjectPtr ids=mesh->giveCellsWithType(*it); + MEDCouplingAutoRefCountObjectPtr ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); + const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); + int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); + for(int i=0;isynchronizeTimeWithSupport(); + return ret.retn(); } void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const @@ -1625,10 +2271,51 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getValueOnMulti(const Da MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { - di=computeTupleIdsToSelectFromCellIds(mesh,start,end); - return mesh->buildPart(start,end); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPart(start,end); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * This method is strictly equivalent to MEDCouplingFieldDiscretizationGauss::buildSubMeshData except that it is optimized for input defined as a range of cell ids. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingFieldDiscretizationGauss::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(stepCellIds!=1)//even for stepCellIds==-1 the output will not be a range + return MEDCouplingFieldDiscretization::buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,di); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : NULL input mesh !"); + int nbOfCells=mesh->getNumberOfCells(); + di=0; beginOut=0; endOut=0; stepOut=stepCellIds; + const char msg[]="MEDCouplingFieldDiscretizationGaussNE::buildSubMeshDataRange : cell #"; + for(int i=0;igetTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + { std::ostringstream oss; oss << msg << i << " presence of dynamic cell (polygons and polyedrons) ! Not implemented !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + int delta=cm.getNumberOfNodes(); + if(i=endCellIds) + break; + } + MEDCouplingAutoRefCountObjectPtr ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + return ret.retn(); } + /*! * This method returns a tuple ids selection from cell ids selection [start;end). * This method is called by MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData to return parameter \b di. @@ -1640,8 +2327,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFrom { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds : null mesh !"); - const MEDCouplingAutoRefCountObjectPtr umesh=mesh->buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=umesh->computeNbOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); nbOfNodesPerCell->computeOffsets2(); MEDCouplingAutoRefCountObjectPtr sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); return sel->buildExplicitArrByRanges(nbOfNodesPerCell); @@ -1664,6 +2350,11 @@ void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCellsR(const MEDCoup throw INTERP_KERNEL::Exception("Not implemented yet !"); } +void MEDCouplingFieldDiscretizationGaussNE::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Gauss points on nodes per element spatial discretization."; +} + MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other) { } @@ -1678,6 +2369,11 @@ const char *MEDCouplingFieldDiscretizationKriging::getRepr() const return REPR; } +/*! + * This method is simply called by MEDCouplingFieldDiscretization::deepCpy. It performs the deep copy of \a this. + * + * \sa MEDCouplingFieldDiscretization::deepCpy. + */ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationKriging::clone() const { return new MEDCouplingFieldDiscretizationKriging; @@ -1696,6 +2392,11 @@ void MEDCouplingFieldDiscretizationKriging::checkCompatibilityWithNature(NatureO bool MEDCouplingFieldDiscretizationKriging::isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const { + if(!other) + { + reason="other spatial discretization is NULL, and this spatial discretization (Kriginig) is defined."; + return false; + } const MEDCouplingFieldDiscretizationKriging *otherC=dynamic_cast(other); bool ret=otherC!=0; if(!ret) @@ -1705,6 +2406,8 @@ bool MEDCouplingFieldDiscretizationKriging::isEqualIfNotWhy(const MEDCouplingFie MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationKriging::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getMeasureField : mesh instance specified is NULL !"); throw INTERP_KERNEL::Exception("getMeasureField on FieldDiscretizationKriging : not implemented yet !"); } @@ -1716,6 +2419,8 @@ void MEDCouplingFieldDiscretizationKriging::getValueOn(const DataArrayDouble *ar DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getValueOnMulti : NULL input mesh !"); MEDCouplingAutoRefCountObjectPtr coords=getLocalizationOfDiscValues(mesh); int nbOfPts=coords->getNumberOfTuples(); int dimension=coords->getNumberOfComponents(); @@ -1745,8 +2450,12 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const Da MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbOfTargetPoints,nbOfCompo); INTERP_KERNEL::matrixProduct(KnewiK->getConstPointer(),1,nbOfPts+delta,matrix3->getConstPointer(),nbOfPts+delta,nbOfTargetPoints*nbOfCompo,ret->getPointer()); - ret->incrRef(); - return ret; + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationKriging::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Kriging spatial discretization."; } /*! @@ -1761,6 +2470,8 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const Da */ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficients : NULL input mesh !"); MEDCouplingAutoRefCountObjectPtr coords=getLocalizationOfDiscValues(mesh); int nbOfPts=coords->getNumberOfTuples(); //int dimension=coords->getNumberOfComponents(); @@ -1779,8 +2490,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficie double *work=std::copy(arr->begin(),arr->end(),arr2->getPointer()); std::fill(work,work+isDrift,0.); INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbOfPts+isDrift,nbOfPts+isDrift,arr2->getConstPointer(),nbOfPts+isDrift,1,KnewiK->getPointer()); - KnewiK->incrRef(); - return KnewiK; + return KnewiK.retn(); } /*! @@ -1850,7 +2560,5 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataA destWork+=spaceDimension; } // - ret->incrRef(); - return ret; + return ret.retn(); } - diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 6efe4aae1..962f6fd8c 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -34,6 +34,7 @@ namespace ParaMEDMEM { + class DataArray; class DataArrayInt; class MEDCouplingMesh; class DataArrayDouble; @@ -46,36 +47,40 @@ namespace ParaMEDMEM double getPrecision() const { return _precision; } void setPrecision(double val) { _precision=val; } void updateTime() const; - static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + static TypeOfField GetTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); virtual TypeOfField getEnum() const = 0; virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; + virtual MEDCouplingFieldDiscretization *deepCpy() const; virtual MEDCouplingFieldDiscretization *clone() const = 0; virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; virtual std::string getStringRepr() const = 0; virtual const char *getRepr() const = 0; - virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; + virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const = 0; virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const = 0; virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception); virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception); virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception); virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0; - virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest) = 0; + virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception) = 0; virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) = 0; virtual void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) = 0; virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0; virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0; virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0; virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0; virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; + virtual MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0; virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0; virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0; @@ -96,6 +101,7 @@ namespace ParaMEDMEM virtual std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); virtual void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); + virtual void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; virtual ~MEDCouplingFieldDiscretization(); protected: MEDCouplingFieldDiscretization(); @@ -114,16 +120,16 @@ namespace ParaMEDMEM std::string getStringRepr() const; const char *getRepr() const; bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); - void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest); - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; @@ -132,7 +138,9 @@ namespace ParaMEDMEM void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); public: static const char REPR[]; static const TypeOfField TYPE; @@ -141,16 +149,17 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization { public: - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest); - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; @@ -171,6 +180,7 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); public: static const char REPR[]; static const TypeOfField TYPE; @@ -186,18 +196,22 @@ namespace ParaMEDMEM { public: const DataArrayInt *getArrayOfDiscIds() const; + void setArrayOfDiscIds(const DataArrayInt *adids) throw(INTERP_KERNEL::Exception); + void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); + std::vector splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const throw(INTERP_KERNEL::Exception); protected: MEDCouplingFieldDiscretizationPerCell(); MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds); + MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, int beginCellIds, int endCellIds, int stepCellIds); ~MEDCouplingFieldDiscretizationPerCell(); void updateTime() const; - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); - void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); protected: - void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m); + void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh); protected: DataArrayInt *_discr_per_cell; static const int DFT_INVALID_LOCID_VALUE; @@ -212,16 +226,18 @@ namespace ParaMEDMEM bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; MEDCouplingFieldDiscretization *clone() const; MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; std::string getStringRepr() const; const char *getRepr() const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + std::size_t getHeapMemorySize() const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest); + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception); void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; @@ -229,21 +245,24 @@ namespace ParaMEDMEM void getSerializationIntArray(DataArrayInt *& arr) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + void setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); - void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, + void setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); + void setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc) throw(INTERP_KERNEL::Exception); + void resizeLocalizationVector(int newSz) throw(INTERP_KERNEL::Exception); MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); @@ -251,10 +270,11 @@ namespace ParaMEDMEM std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); - std::vector splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const throw(INTERP_KERNEL::Exception); DataArrayInt *buildNbOfGaussPointPerCellField() const throw(INTERP_KERNEL::Exception); + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); protected: MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds=0, const int *endCellIds=0); + MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, int beginCellIds, int endCellIds, int stepCellIds); void zipGaussLocalizations(); int getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception); void checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception); @@ -277,31 +297,71 @@ namespace ParaMEDMEM std::string getStringRepr() const; const char *getRepr() const; bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, - DataArrayInt *&cellRest); + void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception); + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const throw(INTERP_KERNEL::Exception); void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + static const double *GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth) throw(INTERP_KERNEL::Exception); + static const double *GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth) throw(INTERP_KERNEL::Exception); protected: MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other); public: static const char REPR[]; static const TypeOfField TYPE; + static const double FGP_SEG2[2]; + static const double FGP_SEG3[3]; + static const double FGP_SEG4[4]; + static const double FGP_TRI3[3]; + static const double FGP_TRI6[6]; + static const double FGP_TRI7[7]; + static const double FGP_QUAD4[4]; + //static const double FGP_QUAD8[8]; + static const double FGP_QUAD9[9]; + static const double FGP_TETRA4[4]; + //static const double FGP_TETRA10[10]; + static const double FGP_PENTA6[6]; + //static const double FGP_PENTA15[15]; + static const double FGP_HEXA8[8]; + static const double FGP_HEXA27[27]; + static const double FGP_PYRA5[5]; + //static const double FGP_PYRA13[13]; + static const double REF_SEG2[2]; + static const double REF_SEG3[3]; + static const double REF_SEG4[4]; + static const double REF_TRI3[6]; + static const double REF_TRI6[12]; + static const double REF_TRI7[14]; + static const double REF_QUAD4[8]; + static const double REF_QUAD8[16]; + static const double REF_QUAD9[18]; + static const double REF_TETRA4[12]; + static const double REF_TETRA10[30]; + static const double REF_PENTA6[18]; + static const double REF_PENTA15[45]; + static const double REF_HEXA8[24]; + static const double REF_HEXA20[60]; + static const double REF_HEXA27[81]; + static const double REF_PYRA5[15]; + static const double REF_PYRA13[39]; }; class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes @@ -316,6 +376,7 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); public://specific part DataArrayDouble *computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const; protected: diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 36c10e825..b31721747 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,8 @@ #include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "InterpKernelAutoPtr.hxx" + #include #include #include @@ -33,40 +35,102 @@ using namespace ParaMEDMEM; -MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td) + +/*! + * Creates a new MEDCouplingFieldDouble, of given spatial type and time discretization. + * For more info, see \ref MEDCouplingFirstSteps3. + * \param [in] type - the type of spatial discretization of the created field, one of + * (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", + * \ref ParaMEDMEM::ON_NODES "ON_NODES", + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). + * \param [in] td - the type of time discretization of the created field, one of + * (\ref ParaMEDMEM::NO_TIME "NO_TIME", + * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", + * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", + * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + */ +MEDCouplingFieldDouble* MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTimeDiscretization td) { return new MEDCouplingFieldDouble(type,td); } -MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td) +/*! + * Creates a new MEDCouplingFieldDouble, of a given time discretization and with a + * spatial type and supporting mesh copied from a given + * \ref MEDCouplingFieldTemplatesPage "field template". + * For more info, see \ref MEDCouplingFirstSteps3. + * \warning This method does not deeply copy neither the mesh nor the spatial + * discretization. Only a shallow copy (reference) is done for the mesh and the spatial + * discretization! + * \param [in] ft - the \ref MEDCouplingFieldTemplatesPage "field template" defining + * the spatial discretization and the supporting mesh. + * \param [in] td - the type of time discretization of the created field, one of + * (\ref ParaMEDMEM::NO_TIME "NO_TIME", + * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", + * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", + * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td) { return new MEDCouplingFieldDouble(ft,td); } +/*! + * Sets a time \a unit of \a this field. For more info, see \ref MEDCouplingFirstSteps3. + * \param [in] unit \a unit (string) in which time is measured. + */ void MEDCouplingFieldDouble::setTimeUnit(const char *unit) { _time_discr->setTimeUnit(unit); } +/*! + * Returns a time unit of \a this field. + * \return a string describing units in which time is measured. + */ const char *MEDCouplingFieldDouble::getTimeUnit() const { return _time_discr->getTimeUnit(); } /*! - * This method performs a copy of \a this **without any copy of the underlying mesh** ( see warning section of this method). - * The copy of arrays is deep if \b recDeepCpy equals to true, no copy of arrays is done if \b recDeepCpy equals to false. - * - * \c clone(false) is rather dedicated for advanced users that want to limit the amount of memory. + * This method if possible the time information (time unit, time iteration, time unit and time value) with its support + * that is to say its mesh. * - * It allows the user to perform methods - * MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields with \a this and the returned field. + * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is + * NO_TIME. + */ +void MEDCouplingFieldDouble::synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception) +{ + _time_discr->synchronizeTimeWith(_mesh); +} + +/*! + * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data + * of \a this field is copied either deep or shallow depending on \a recDeepCpy + * parameter. But the underlying mesh is always shallow copied. + * Data that can be copied either deeply or shallow are: + * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) + * of field values, + * - \ref MEDCouplingSpatialDisc "a spatial discretization". * - * \warning The \b underlying \b mesh of the returned field is \b always the same (same pointer) than \a this \b whatever \b the \b value \b of \b recDeepCpy \b parameter. - * If the user wants to duplicated deeply the underlying mesh he should call MEDCouplingFieldDouble::cloneWithMesh method or MEDCouplingFieldDouble::deepCpy instead. - * - * \param [in] recDeepCpy specifies if underlying arrays in \a this should be copied of only attached to the returned field. - * \return a newly allocated MEDCouplingFieldDouble instance that the caller should deal with. + * \c clone(false) is rather dedicated for advanced users that want to limit the amount + * of memory. It allows the user to perform methods like operator+(), operator*() + * etc. with \a this and the returned field. If the user wants to duplicate deeply the + * underlying mesh he should call cloneWithMesh() method or deepCpy() instead. + * \warning The underlying \b mesh of the returned field is **always the same** + * (pointer) as \a this one **whatever the value** of \a recDeepCpy parameter. + * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is + * deep, else all data arrays of \a this field are shared by the new field. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \sa cloneWithMesh() */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const { @@ -74,62 +138,108 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const } /*! - * This method behaves exactly like MEDCouplingFieldDouble::clone method \b except \b that \b here \b the \b underlying \b mesh \b is \b systematically - * (whatever the value of the input parameter 'recDeepCpy') \b deeply \b duplicated.\n \n - * The result of \c cloneWithMesh(true) is exactly the same than calling \ref MEDCouplingFieldDouble::deepCpy "deepCpy". + * Returns a new MEDCouplingFieldDouble which is a copy of \a this one. The data + * of \a this field is copied either deep or shallow depending on \a recDeepCpy + * parameter. But the underlying mesh is always deep copied. + * Data that can be copied either deeply or shallow are: + * - \ref MEDCouplingTemporalDisc "temporal discretization" data that holds array(s) + * of field values, + * - \ref MEDCouplingSpatialDisc "a spatial discretization". * - * So the resulting field of this call cannot be called with \a this with the following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ... - * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead. + * This method behaves exactly like clone() except that here the underlying **mesh is + * always deeply duplicated**, whatever the value \a recDeepCpy parameter. + * The result of \c cloneWithMesh(true) is exactly the same as that of deepCpy(). + * So the resulting field can not be used together with \a this one in the methods + * like operator+(), operator*() etc. To avoid deep copying the underlying mesh, + * the user can call clone(). + * \param [in] recDeepCpy - if \c true, the copy of the underlying data arrays is + * deep, else all data arrays of \a this field are shared by the new field. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \sa clone() */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const { - MEDCouplingFieldDouble *ret=clone(recDeepCpy); + MEDCouplingAutoRefCountObjectPtr ret=clone(recDeepCpy); if(_mesh) { - MEDCouplingMesh *mCpy=_mesh->deepCpy(); + MEDCouplingAutoRefCountObjectPtr mCpy=_mesh->deepCpy(); ret->setMesh(mCpy); - mCpy->decrRef(); } - return ret; + return ret.retn(); } /*! - * This method performs a deepCpy of \a this \b mesh \b included ! - * So the resulting field of this call cannot be called with \a this with following methods MEDCouplingFieldDouble::AddFields, MEDCouplingFieldDouble::MultiplyFields ... - * To avoid to deep copy the underlying mesh the user should call MEDCouplingFieldDouble::clone method instead. - * This method is exactly equivalent to MEDCouplingFieldDouble::cloneWithMesh called with parameter true. + * Returns a new MEDCouplingFieldDouble which is a deep copy of \a this one **including + * the mesh**. + * The result of this method is exactly the same as that of \c cloneWithMesh(true). + * So the resulting field can not be used together with \a this one in the methods + * like operator+(), operator*() etc. To avoid deep copying the underlying mesh, + * the user can call clone(). + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \sa cloneWithMesh() */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deepCpy() const { return cloneWithMesh(true); } +/*! + * Creates a new MEDCouplingFieldDouble of given + * \ref MEDCouplingTemporalDisc "temporal discretization". The result field either + * shares the data array(s) with \a this field, or holds a deep copy of it, depending on + * \a deepCopy parameter. But the underlying \b mesh is always **shallow copied**. + * \param [in] td - the type of time discretization of the created field, one of + * (\ref ParaMEDMEM::NO_TIME "NO_TIME", + * \ref ParaMEDMEM::ONE_TIME "ONE_TIME", + * \ref ParaMEDMEM::LINEAR_TIME "LINEAR_TIME", + * \ref ParaMEDMEM::CONST_ON_TIME_INTERVAL "CONST_ON_TIME_INTERVAL"). + * \param [in] deepCopy - if \c true, the copy of the underlying data arrays is + * deep, else all data arrays of \a this field are shared by the new field. + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * + * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."
+ * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." + * \sa clone() + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const { MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone()); + MEDCouplingAutoRefCountObjectPtr disc; + if(_type) + disc=_type->clone(); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()); ret->setMesh(getMesh()); ret->setName(getName()); ret->setDescription(getDescription()); - return ret; + return ret.retn(); } /*! - * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason). + * Copies tiny info (component names, name and description) from an \a other field to + * \a this one. + * \warning The underlying mesh is not renamed (for safety reason). + * \param [in] other - the field to copy the tiny info from. + * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() */ -void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception) { - if(other) + MEDCouplingField::copyTinyStringsFrom(other); + const MEDCouplingFieldDouble *otherC=dynamic_cast(other); + if(otherC) { - setName(other->_name.c_str()); - setDescription(other->_desc.c_str()); - _time_discr->copyTinyStringsFrom(*other->_time_discr); + _time_discr->copyTinyStringsFrom(*otherC->_time_discr); } } /*! - * Copy only times, order, iteration from other. The underlying mesh is not impacted by this method. - * Arrays are not impacted too. + * Copies only times, order and iteration from an \a other field to + * \a this one. The underlying mesh is not impacted by this method. + * Arrays are not impacted neither. + * \param [in] other - the field to tiny attributes from. + * \throw If \a this->getNumberOfComponents() != \a other->getNumberOfComponents() */ void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception) { @@ -137,24 +247,57 @@ void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *othe { _time_discr->copyTinyAttrFrom(*other->_time_discr); } + +} + +void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception) +{ + copyTinyStringsFrom(other); + copyTinyAttrFrom(other); } +/*! + * Returns a string describing \a this field. This string is outputted by \c print + * Python command. The string includes info on + * - name, + * - description, + * - \ref MEDCouplingSpatialDisc "spatial discretization", + * - \ref MEDCouplingTemporalDisc "time discretization", + * - \ref NatureOfField, + * - components, + * - mesh. + * + * \return std::string - the string describing \a this field. + */ std::string MEDCouplingFieldDouble::simpleRepr() const { std::ostringstream ret; ret << "FieldDouble with name : \"" << getName() << "\"\n"; ret << "Description of field is : \"" << getDescription() << "\"\n"; - ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; - ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; - ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n"; + if(_type) + { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } + else + { ret << "FieldDouble has no spatial discretization !\n"; } + if(_time_discr) + { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } + else + { ret << "FieldDouble has no time discretization !\n"; } + ret << "FieldDouble nature of field is : \"" << MEDCouplingNatureOfField::GetReprNoThrow(_nature) << "\"\n"; if(getArray()) { - int nbOfCompo=getArray()->getNumberOfComponents(); - ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; - ret << "FieldDouble default array has following info on components : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; + if(getArray()->isAllocated()) + { + int nbOfCompo=getArray()->getNumberOfComponents(); + ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; + ret << "FieldDouble default array has following info on components : "; + for(int i=0;igetInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + { + ret << "Array set but not allocated !\n"; + } } if(_mesh) ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); @@ -163,13 +306,31 @@ std::string MEDCouplingFieldDouble::simpleRepr() const return ret.str(); } +/*! + * Returns a string describing \a this field. The string includes info on + * - name, + * - description, + * - \ref MEDCouplingSpatialDisc "spatial discretization", + * - \ref MEDCouplingTemporalDisc "time discretization", + * - components, + * - mesh, + * - contents of data arrays. + * + * \return std::string - the string describing \a this field. + */ std::string MEDCouplingFieldDouble::advancedRepr() const { std::ostringstream ret; ret << "FieldDouble with name : \"" << getName() << "\"\n"; ret << "Description of field is : \"" << getDescription() << "\"\n"; - ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; - ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; + if(_type) + { ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; } + else + { ret << "FieldDouble has no space discretization set !\n"; } + if(_time_discr) + { ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; } + else + { ret << "FieldDouble has no time discretization set !\n"; } if(getArray()) ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; if(_mesh) @@ -191,6 +352,12 @@ std::string MEDCouplingFieldDouble::advancedRepr() const return ret.str(); } +void MEDCouplingFieldDouble::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception) +{ + std::vector fs(1,this); + MEDCouplingFieldDouble::WriteVTK(fileName,fs); +} + bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!other) @@ -211,6 +378,16 @@ bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, doub return true; } +/*! + * Checks equality of \a this and \a other field. Only numeric data is considered, + * i.e. names, description etc are not compared. + * \param [in] other - the field to compare with. + * \param [in] meshPrec - a precision used to compare node coordinates of meshes. + * \param [in] valsPrec - a precision used to compare data arrays of the two fields. + * \return bool - \c true if the two fields are equal, \c false else. + * \throw If \a other == NULL. + * \throw If the spatial discretization of \a this field is NULL. + */ bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const { const MEDCouplingFieldDouble *otherC=dynamic_cast(other); @@ -303,8 +480,24 @@ bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble * } /*! - * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same. - * The values of field are impacted in consequence to have the same geometrical field. + * Permutes values of \a this field according to a given permutation array for cells + * renumbering. The underlying mesh is deeply copied and its cells are also permuted. + * The number of cells remains the same; for that the permutation array \a old2NewBg + * should not contain equal ids. + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfCells(). + * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation + * array, so that its maximal cell id to correspond to (be less than) the number + * of cells in mesh. This new array is then used for the renumbering. If \a + * check == \c false, \a old2NewBg is used as is, that is less secure as validity + * of ids in \a old2NewBg is not checked. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a check == \c true and \a old2NewBg contains equal ids. + * \throw If mesh nature does not allow renumbering (e.g. structured mesh). + * + * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
+ * \ref py_mcfielddouble_renumberCells "Here is a Python example". */ void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { @@ -316,29 +509,60 @@ void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) thr } /*! - * \b WARNING : use this method with lot of care ! - * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh. - * That is to say, the field content is changed by this method. The reason of this method is only for multi-field instances lying on the same mesh to - * avoid a systematic duplication and renumbering of _mesh attribute. + * Permutes values of \a this field according to a given permutation array for cells + * renumbering. The underlying mesh is \b not permuted. + * The number of cells remains the same; for that the permutation array \a old2NewBg + * should not contain equal ids. + * This method performs a part of job of renumberCells(). The reasonable use of this + * method is only for multi-field instances lying on the same mesh to avoid a + * systematic duplication and renumbering of _mesh attribute. + * \warning Use this method with a lot of care! + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfCells(). + * \param [in] check - if \c true, \a old2NewBg is transformed to a new permutation + * array, so that its maximal cell id to correspond to (be less than) the number + * of cells in mesh. This new array is then used for the renumbering. If \a + * check == \c false, \a old2NewBg is used as is, that is less secure as validity + * of ids in \a old2NewBg is not checked. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a check == \c true and \a old2NewBg contains equal ids. + * \throw If mesh nature does not allow renumbering (e.g. structured mesh). */ void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { if(!_mesh) - throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); + throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); // _type->renumberCells(old2NewBg,check); std::vector arrays; _time_discr->getArrays(arrays); - _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check); + std::vector arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); + _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); // updateTime(); } /*! - * This method performs a clone of mesh and a renumbering of underlying nodes of it. The number of nodes remains not compulsory the same as renumberCells method. - * The values of field are impacted in consequence to have the same geometrical field. + * Permutes values of \a this field according to a given permutation array for node + * renumbering. The underlying mesh is deeply copied and its nodes are also permuted. + * The number of nodes can change, contrary to renumberCells(). + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfNodes(). + * \param [in] eps - a precision used to compare field values at merged nodes. If + * the values differ more than \a eps, an exception is thrown. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a check == \c true and \a old2NewBg contains equal ids. + * \throw If mesh nature does not allow renumbering (e.g. structured mesh). + * \throw If values at merged nodes deffer more than \a eps. + * + * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".
+ * \ref py_mcfielddouble_renumberNodes "Here is a Python example". */ -void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) throw(INTERP_KERNEL::Exception) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) @@ -346,18 +570,37 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KE int nbOfNodes=meshC->getNumberOfNodes(); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; - renumberNodesWithoutMesh(old2NewBg,newNbOfNodes); + renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); meshC2->renumberNodes(old2NewBg,newNbOfNodes); setMesh(meshC2); } /*! - * \b WARNING : use this method with lot of care ! - * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh. - * That is to say, the field content is changed by this method. + * Permutes values of \a this field according to a given permutation array for nodes + * renumbering. The underlying mesh is \b not permuted. + * The number of nodes can change, contrary to renumberCells(). + * A given epsilon specifies a threshold of error in case of two nodes are merged but + * the difference of values on these nodes are higher than \a eps. + * This method performs a part of job of renumberNodes(), excluding node renumbering + * in mesh. The reasonable use of this + * method is only for multi-field instances lying on the same mesh to avoid a + * systematic duplication and renumbering of _mesh attribute. + * \warning Use this method with a lot of care! + * \warning In case of an exception thrown, the contents of the data array can be + * partially modified until the exception occurs. + * \param [in] old2NewBg - the permutation array in "Old to New" mode. Its length is + * to be equal to \a this->getMesh()->getNumberOfNodes(). + * \param [in] newNbOfNodes - a number of nodes in the mesh after renumbering. + * \param [in] eps - a precision used to compare field values at merged nodes. If + * the values differ more than \a eps, an exception is thrown. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If values at merged nodes deffer more than \a eps. */ void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); std::vector arrays; _time_discr->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) @@ -366,10 +609,17 @@ void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int } /*! - * This method makes the assumption that the default array is set. If not an exception will be thrown. - * This method is usable only if the default array has exactly one component. If not an exception will be thrown too. - * This method returns all tuples ids that fit the range [vmin,vmax]. - * The caller has the responsability of the returned DataArrayInt. + * Returns all tuple ids of \a this scalar field that fit the range [\a vmin, + * \a vmax]. This method calls DataArrayDouble::getIdsInRange(). + * \param [in] vmin - a lower boundary of the range. Tuples with values less than \a + * vmin are not included in the result array. + * \param [in] vmax - an upper boundary of the range. Tuples with values more than \a + * vmax are not included in the result array. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of selected + * tuples. The caller is to delete this array using decrRef() as it is no + * more needed. + * \throw If the data array is not set. + * \throw If \a this->getNumberOfComponents() != 1. */ DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception) { @@ -379,73 +629,88 @@ DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) co } /*! - * Builds a newly created field, that the caller will have the responsability to deal with (decrRef). + * Builds a newly created field, that the caller will have the responsability to deal with (decrRef()). * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. - * This method returns a restriction of \a this so that only tuples id specified in 'part' will be contained in returned field. - * Parameter 'part' specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this (ON_CELLS, ON_NODES, ON_GAUSS_PT, ON_GAUSS_NE) + * This method returns a restriction of \a this so that only tuples with ids specified in \a part will be contained in the returned field. + * Parameter \a part specifies **cell ids whatever the spatial discretization of this** ( + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", + * \ref ParaMEDMEM::ON_NODES "ON_NODES", + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). + * + * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a part contains following cell ids [3,7,6]. + * Then the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples.
+ * Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh().
+ * Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh().
+ * Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). + * + * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a part contains following cellIds [3,7,6]. + * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field + * will contain 6 tuples and \a this field will lie on this restricted mesh. * - * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6]. - * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples. - * Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of 'this->getMesh()' - * Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of 'this->getMesh()' - * Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of 'this->getMesh()' + * \param [in] part - an array of cell ids to include to the result field. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The caller is to delete this field using decrRef() as it is no more needed. * - * If \a this is field on node lying on a mesh that have 10 cells and 11 nodes for example. If part contains following cellIds [3,7,6]. - * \a this is currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field, - * will contain 6 tuples and this field will lie on this restricted mesh. + * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
+ * \ref py_mcfielddouble_subpart1 "Here is a Python example". + * \sa MEDCouplingFieldDouble::buildSubPartRange */ + MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception) { if(part==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - const int *start=part->getConstPointer(); - const int *end=start+part->getNbOfElems(); - return buildSubPart(start,end); + return buildSubPart(part->begin(),part->end()); } /*! * Builds a newly created field, that the caller will have the responsability to deal with. - * \n This method makes the assumption that the field \a this is correctly defined when this method is called (\c this->checkCoherency() returns without any exception thrown), **no check of this will be done**. - * \n This method returns a restriction of \a this so that only tuples id specified in [ \a partBg , \a partEnd ) will be contained in returned field. - * \n Parameter [\a partBg, \a partEnd ) specifies \b cell \b ids \b whatever \b the \b spatial \b discretization of \a this - * (\ref ParaMEDMEM::ON_CELLS "ON_CELLS", \ref ParaMEDMEM::ON_NODES "ON_CELLS", \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE") - * - * If \a this is a field on cell lying on a mesh that have 10 cells. If part contains following cellIds [3,7,6]. - * In this case the returned field will lie on mesh having 3 cells and the returned field will contain 3 tuples. + * \n This method makes the assumption that \a this field is correctly defined when this method is called (\a this->checkCoherency() returns without any exception thrown), **no check of this will be done**. + * \n This method returns a restriction of \a this so that only tuple ids specified in [ \a partBg , \a partEnd ) will be contained in the returned field. + * \n Parameter [\a partBg, \a partEnd ) specifies **cell ids whatever the spatial discretization** of \a this ( + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", + * \ref ParaMEDMEM::ON_NODES "ON_NODES", + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE", + * \ref ParaMEDMEM::ON_NODES_KR "ON_NODES_KR"). * - *- Tuple#0 of return field will refer to the cell#0 of returned mesh. The cell #0 of returned mesh will be equal to the cell#3 of \c this->getMesh() - *- Tuple#1 of return field will refer to the cell#1 of returned mesh. The cell #1 of returned mesh will be equal to the cell#7 of \c this->getMesh() - *- Tuple#2 of return field will refer to the cell#2 of returned mesh. The cell #2 of returned mesh will be equal to the cell#6 of \c this->getMesh() + * For example, \a this is a field on cells lying on a mesh that have 10 cells, \a partBg contains the following cell ids [3,7,6]. + * Then the returned field will lie on mesh having 3 cells and will contain 3 tuples. + *- Tuple #0 of the result field will refer to the cell #0 of returned mesh. The cell #0 of returned mesh will be equal to the cell #3 of \a this->getMesh(). + *- Tuple #1 of the result field will refer to the cell #1 of returned mesh. The cell #1 of returned mesh will be equal to the cell #7 of \a this->getMesh(). + *- Tuple #2 of the result field will refer to the cell #2 of returned mesh. The cell #2 of returned mesh will be equal to the cell #6 of \a this->getMesh(). * - * If \a this is field on node lying on a mesh that have 10 cells and 11 nodes for example. So \a this is currently contains 11 tuples. - * \n If part contains following cellIds [3,7,6]. - * \n If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, the returned field, - * will contain 6 tuples (and same number of components \c this->getArray()->getNumberOfComponents() ) and this field will lie on this restricted mesh. + * Let, for example, \a this be a field on nodes lying on a mesh that have 10 cells and 11 nodes, and \a partBg contains following cellIds [3,7,6]. + * Thus \a this currently contains 11 tuples. If the restriction of mesh to 3 cells leads to a mesh with 6 nodes, then the returned field + * will contain 6 tuples and \a this field will lie on this restricted mesh. * - * \param [in] partBg start (included) of input range cell ids to select [ \a partBg, \a partEnd ) - * \param [in] partEnd end (not included) of input range cell ids to select [ \a partBg, \a partEnd ) + * \param [in] partBg - start (included) of input range of cell ids to select [ \a partBg, \a partEnd ) + * \param [in] partEnd - end (not included) of input range of cell ids to select [ \a partBg, \a partEnd ) * \return a newly allocated field the caller should deal with. * - * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \c this->getMesh() - * - * \ref cpp_mcfielddouble_subpart1 "Here a C++ example." + * \throw if there is presence of an invalid cell id in [ \a partBg, \a partEnd ) regarding the number of cells of \a this->getMesh(). * + * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
* \ref py_mcfielddouble_subpart1 "Here a Python example." - * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const + * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); DataArrayInt *arrSelect; MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); - MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy. + MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. const MEDCouplingFieldDiscretization *disc=getDiscretization(); if(disc) - ret->setDiscretization(disc->clonePart(partBg,partEnd)); + ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePart(partBg,partEnd))); ret->setMesh(m); std::vector arrays; _time_discr->getArrays(arrays); std::vector arrs; + std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; const int *arrSelBg=arrSelect->begin(); const int *arrSelEnd=arrSelect->end(); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) @@ -453,15 +718,60 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, DataArrayDouble *arr=0; if(*iter) arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - arrs.push_back(arr); + arrs.push_back(arr); arrsSafe.push_back(arr); } ret->_time_discr->setArrays(arrs,0); - for(std::vector::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) - if(*iter) - (*iter)->decrRef(); - return ret; + return ret.retn(); } +/*! + * This method is equivalent to MEDCouplingFieldDouble::buildSubPart, the only difference is that the input range of cell ids is + * given using a range given \a begin, \a end and \a step to optimize the part computation. + * + * \sa MEDCouplingFieldDouble::buildSubPart + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + int beginOut,endOut,stepOut; + MEDCouplingAutoRefCountObjectPtr m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect); + MEDCouplingAutoRefCountObjectPtr arrSelect2(arrSelect); + MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr(disc->clonePartRange(begin,end,step))); + ret->setMesh(m); + std::vector arrays; + _time_discr->getArrays(arrays); + std::vector arrs; + std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + DataArrayDouble *arr=0; + if(*iter) + { + if(arrSelect) + { + const int *arrSelBg=arrSelect->begin(); + const int *arrSelEnd=arrSelect->end(); + arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); + } + else + arr=(*iter)->selectByTupleId2(beginOut,endOut,stepOut); + } + arrs.push_back(arr); arrsSafe.push_back(arr); + } + ret->_time_discr->setArrays(arrs,0); + return ret.retn(); +} + +/*! + * Returns a type of \ref MEDCouplingTemporalDisc "time discretization" of \a this field. + * \return ParaMEDMEM::TypeOfTimeDiscretization - an enum item describing the time + * discretization type. + */ TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const { return _time_discr->getEnum(); @@ -472,12 +782,15 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscr { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft), +/*! + * ** WARINING : This method do not deeply copy neither mesh nor spatial discretization. Only a shallow copy (reference) is done for mesh and spatial discretization ! ** + */ +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft,false), _time_discr(MEDCouplingTimeDiscretization::New(td)) { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other), +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy), _time_discr(other._time_discr->performCpy(deepCopy)) { } @@ -491,16 +804,32 @@ MEDCouplingFieldDouble::~MEDCouplingFieldDouble() delete _time_discr; } +/*! + * Checks if \a this field is correctly defined, else an exception is thrown. + * \throw If the mesh is not set. + * \throw If the data array is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a this->getTimeTolerance() < 0. + * \throw If the temporal discretization data is incorrect. + * \throw If mesh data does not correspond to field data. + */ void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::checkCoherency : no spatial discretization !"); _time_discr->checkCoherency(); _type->checkCoherencyBetween(_mesh,getArray()); } /*! - * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array. + * Accumulate values of a given component of \a this field. + * \param [in] compId - the index of the component of interest. + * \return double - a sum value of *compId*-th component. + * \throw If the data array is not set. + * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is + * not respected. */ double MEDCouplingFieldDouble::accumulate(int compId) const { @@ -510,8 +839,11 @@ double MEDCouplingFieldDouble::accumulate(int compId) const } /*! - * Returns the accumulation (the sum) of all tuples of \b default and \b only default array. - * The res is expected to be of size getNumberOfComponents(). + * Accumulates values of each component of \a this array. + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * by the caller, that is filled by this method with sum value for each + * component. + * \throw If the data array is not set. */ void MEDCouplingFieldDouble::accumulate(double *res) const { @@ -521,9 +853,12 @@ void MEDCouplingFieldDouble::accumulate(double *res) const } /*! - * This method returns the max value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. - * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'. - * If no arrays exists, an exception will be thrown. + * Returns the maximal value within \a this scalar field. Values of all arrays stored + * in \a this->_time_discr are checked. + * \return double - the maximal value among all values of \a this field. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If the data array is not set. + * \throw If there is an empty data array in \a this field. */ double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception) { @@ -546,11 +881,14 @@ double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exceptio } /*! - * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned - * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility - * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array. - * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used - * to compute tupleIds. + * Returns the maximal value and all its locations within \a this scalar field. + * Only the first of available data arrays is checked. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the maximal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the maximal value among all values of the first array of \a this filed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If there is an empty data array in \a this field. */ double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { @@ -559,6 +897,7 @@ double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw double ret=-std::numeric_limits::max(); bool isExistingArr=false; tupleIds=0; + MEDCouplingAutoRefCountObjectPtr ret1; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) @@ -566,21 +905,24 @@ double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw isExistingArr=true; DataArrayInt *tmp; ret=std::max(ret,(*iter)->getMaxValue2(tmp)); - if(!tupleIds) - tupleIds=tmp; - else - tmp->decrRef(); + MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); + if(!((const DataArrayInt *)ret1)) + ret1=tmpSafe; } } if(!isExistingArr) throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !"); + tupleIds=ret1.retn(); return ret; } /*! - * This method returns the min value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. - * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'. - * If no arrays exists, an exception will be thrown. + * Returns the minimal value within \a this scalar field. Values of all arrays stored + * in \a this->_time_discr are checked. + * \return double - the minimal value among all values of \a this field. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If the data array is not set. + * \throw If there is an empty data array in \a this field. */ double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception) { @@ -603,11 +945,14 @@ double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exceptio } /*! - * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned - * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility - * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array. - * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used - * to compute tupleIds. + * Returns the minimal value and all its locations within \a this scalar field. + * Only the first of available data arrays is checked. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the minimal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the minimal value among all values of the first array of \a this filed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If there is an empty data array in \a this field. */ double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { @@ -616,6 +961,7 @@ double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw double ret=-std::numeric_limits::max(); bool isExistingArr=false; tupleIds=0; + MEDCouplingAutoRefCountObjectPtr ret1; for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) { if(*iter) @@ -623,21 +969,22 @@ double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw isExistingArr=true; DataArrayInt *tmp; ret=std::max(ret,(*iter)->getMinValue2(tmp)); - if(!tupleIds) - tupleIds=tmp; - else - tmp->decrRef(); + MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); + if(!((const DataArrayInt *)ret1)) + ret1=tmpSafe; } } if(!isExistingArr) throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !"); + tupleIds=ret1.retn(); return ret; } /*! - * This method returns the average value in \a this. \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. - * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. - * If default array does not exist, an exception will be thrown. + * Returns the average value of \a this scalar field. + * \return double - the average value over all values of the data array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If the data array is not set or it is empty. */ double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) { @@ -647,11 +994,11 @@ double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exce } /*! - * This method returns the euclidean norm of \a this. + * This method returns the euclidean norm of \a this field. * \f[ * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]} * \f] - * If default array does not exist, an exception will be thrown. + * \throw If the data array is not set. */ double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception) { @@ -661,11 +1008,11 @@ double MEDCouplingFieldDouble::norm2() const throw(INTERP_KERNEL::Exception) } /*! - * This method returns the max norm of \a this. + * This method returns the max norm of \a this field. * \f[ * \max_{0 \leq i < nbOfEntity}{abs(val[i])} * \f] - * If default array does not exist, an exception will be thrown. + * \throw If the data array is not set. */ double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception) { @@ -675,194 +1022,301 @@ double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception) } /*! - * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField. - * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. - * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. - * If default array does not exist, an exception will be thrown. + * Computes sums of values of each component of \a this field wighted with + * values returned by buildMeasureField(). + * \param [out] res - pointer to an array of result sum values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by + * buildMeasureField() that makes this method slower. If a user is sure that all + * cells of the underlying mesh have correct orientation, he can put \a isWAbs == + * \c false that speeds up this method. + * \throw If the mesh is not set. + * \throw If the data array is not set. */ -double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const throw(INTERP_KERNEL::Exception) { if(getArray()==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); - MEDCouplingFieldDouble *w=buildMeasureField(true); + MEDCouplingAutoRefCountObjectPtr w=buildMeasureField(isWAbs); double deno=w->getArray()->accumulate(0); - w->getArray()->multiplyEqual(getArray()); - double res=w->getArray()->accumulate(0); - w->decrRef(); - return res/deno; + MEDCouplingAutoRefCountObjectPtr arr=getArray()->deepCpy(); + arr->multiplyEqual(w->getArray()); + std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies(),1./deno)); + arr->accumulate(res); } /*! - * Returns the normL1 of current field on compId component : + * Computes a sum of values of a given component of \a this field wighted with + * values returned by buildMeasureField(). + * \param [in] compId - an index of the component of interest. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by + * buildMeasureField() that makes this method slower. If a user is sure that all + * cells of the underlying mesh have correct orientation, he can put \a isWAbs == + * \c false that speeds up this method. + * \throw If the mesh is not set. + * \throw If the data array is not set. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). + */ +double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception) +{ + int nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=nbComps) + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + getWeightedAverageValue(res,isWAbs); + return res[compId]; +} + +/*! + * Returns the \c normL1 of values of a given component of \a this field: * \f[ * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} * \f] - * If compId>=nbOfComponent an exception is thrown. + * \param [in] compId - an index of the component of interest. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). */ double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception) { if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1 !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try + if(compId<0 || compId>=nbComps) { - _type->normL1(_mesh,getArray(),res); + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - catch(INTERP_KERNEL::Exception& e) - { - delete [] res; - throw e; - } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->normL1(_mesh,getArray(),res); + return res[compId]; } /*! - * Returns the normL1 of current field on each components : + * Returns the \c normL1 of values of each component of \a this field: * \f[ * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} * \f] - * The res is expected to be of size getNumberOfComponents(). + * \param [out] res - pointer to an array of result values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. */ void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL1 !"); _type->normL1(_mesh,getArray(),res); } /*! - * Returns the normL2 of current field on compId component : + * Returns the \c normL2 of values of a given component of \a this field: * \f[ * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} * \f] - * If compId>=nbOfComponent an exception is thrown. + * \param [in] compId - an index of the component of interest. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). */ double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try + if(compId<0 || compId>=nbComps) { - _type->normL2(_mesh,getArray(),res); + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - catch(INTERP_KERNEL::Exception& e) - { - delete [] res; - throw e; - } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->normL2(_mesh,getArray(),res); + return res[compId]; } /*! - * Returns the normL2 of current field on each components : + * Returns the \c normL2 of values of each component of \a this field: * \f[ * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} * \f] - * The res is expected to be of size getNumberOfComponents(). + * \param [out] res - pointer to an array of result values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. */ void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform normL2 !"); _type->normL2(_mesh,getArray(),res); } /*! - * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field - * returns by getWeightingField relative of the _type of field of default array. - * This method is usefull to check the conservativity of interpolation method. + * Computes a sum of values of a given component of \a this field multiplied by + * values returned by buildMeasureField(). + * This method is useful to check the conservativity of interpolation method. + * \param [in] compId - an index of the component of interest. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by + * buildMeasureField() that makes this method slower. If a user is sure that all + * cells of the underlying mesh have correct orientation, he can put \a isWAbs == + * \c false that speeds up this method. + * \throw If the mesh is not set. + * \throw If the data array is not set. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). */ double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral !"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try - { - _type->integral(_mesh,getArray(),isWAbs,res); - } - catch(INTERP_KERNEL::Exception& e) + if(compId<0 || compId>=nbComps) { - delete [] res; - throw e; + std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->integral(_mesh,getArray(),isWAbs,res); + return res[compId]; } /*! - * Returns the accumulation (the sum) of each tuples weigthed by the field - * returns by getWeightingField relative of the _type of field of default array. - * This method is usefull to check the conservativity of interpolation method. + * Computes a sum of values of each component of \a this field multiplied by + * values returned by buildMeasureField(). + * This method is useful to check the conservativity of interpolation method. + * \param [in] isWAbs - if \c true (default), \c abs() is applied to the weighs computed by + * buildMeasureField() that makes this method slower. If a user is sure that all + * cells of the underlying mesh have correct orientation, he can put \a isWAbs == + * \c false that speeds up this method. + * \param [out] res - pointer to an array of result sum values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the mesh is not set. + * \throw If the data array is not set. + * \throw If the spatial discretization of \a this field is NULL. */ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform integral2 !"); _type->integral(_mesh,getArray(),isWAbs,res); } /*! - * This method is reserved for field lying on structured mesh spatial support. It returns the value of cell localized by (i,j,k) - * If spatial support is not structured mesh an exception will be thrown. - * @param res out array expected to be equal to size getNumberOfComponents() + * Returns a value at a given cell of a structured mesh. The cell is specified by its + * (i,j,k) index. + * \param [in] i - a index of node coordinates array along X axis. The cell is + * located between the i-th and ( i + 1 )-th nodes along X axis. + * \param [in] j - a index of node coordinates array along Y axis. The cell is + * located between the j-th and ( j + 1 )-th nodes along Y axis. + * \param [in] k - a index of node coordinates array along Z axis. The cell is + * located between the k-th and ( k + 1 )-th nodes along Z axis. + * \param [out] res - pointer to an array returning a feild value, of size at least + * \a this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If the mesh is not a structured one. + * + * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".
+ * \ref py_mcfielddouble_getValueOnPos "Here is a Python example". */ 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"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); _type->getValueOnPos(arr,_mesh,i,j,k,res); } /*! - * Returns value of \a this on default time of point 'spaceLoc' using spatial discretization. - * If 'point' is outside the spatial discretization of this an exception will be thrown. + * Returns a value of \a this at a given point using spatial discretization. + * \param [in] spaceLoc - the point of interest. + * \param [out] res - pointer to an array returning a feild value, of size at least + * \a this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If \a spaceLoc is out of the spatial discretization. + * + * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".
+ * \ref py_mcfielddouble_getValueOn "Here is a Python example". */ 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"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnPos !"); _type->getValueOn(arr,_mesh,spaceLoc,res); } /*! - * Returns a newly allocated array with 'nbOfPoints' tuples and nb of components equal to 'this->getNumberOfComponents()'. + * Returns values of \a this at given points using spatial discretization. + * \param [in] spaceLoc - coordinates of points of interest in full-interlace + * mode. This array is to be of size ( \a nbOfPoints * \a this->getNumberOfComponents() ). + * \param [in] nbOfPoints - number of points of interest. + * \return DataArrayDouble * - a new instance of DataArrayDouble holding field + * values relating to the input points. This array is of size \a nbOfPoints + * tuples per \a this->getNumberOfComponents() components. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If any point in \a spaceLoc is out of the spatial discretization. + * + * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".
+ * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". */ 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"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOnMulti !"); return _type->getValueOnMulti(arr,_mesh,spaceLoc,nbOfPoints); } /*! - * Returns value of \a this on time 'time' of point 'spaceLoc' using spatial discretization. - * If 'time' is not covered by this->_time_discr an exception will be thrown. - * If 'point' is outside the spatial discretization of this an exception will be thrown. + * Returns a value of \a this field at a given point at a given time using spatial discretization. + * If the time is not covered by \a this->_time_discr, an exception is thrown. + * \param [in] spaceLoc - the point of interest. + * \param [in] time - the time of interest. + * \param [out] res - pointer to an array returning a feild value, of size at least + * \a this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If \a spaceLoc is out of the spatial discretization. + * \throw If \a time is not covered by \a this->_time_discr. + * + * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".
+ * \ref py_mcfielddouble_getValueOn_time "Here is a Python example". */ 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"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getValueOn !"); std::vector res2; for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) { @@ -874,7 +1328,12 @@ void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, dou } /*! - * Applies a*x+b on 'compoId'th component of each cell. + * Apply a liner function to a given component of \a this field, so that + * a component value (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If the data array(s) is(are) not set. */ void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) { @@ -890,70 +1349,183 @@ MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(IN { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform operator = !"); int nbOfTuple=_type->getNumberOfTuples(_mesh); - _time_discr->setUniformValue(nbOfTuple,1,value); + _time_discr->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); return *this; } /*! - * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic. - * See MEDCouplingMesh::fillFromAnalytic method doc to have more details. - * The main difference is that the field as been started to be constructed here. - * An exception is thrown if no underlying mesh is set before the call of this method. + * Creates data array(s) of \a this field by using a C function for value generation. + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a field value basing on coordinates of value + * location point. + * \throw If the mesh is not set. + * \throw If \a func returns \c false. + * \throw If the spatial discretization of \a this field is NULL. + * + * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); _time_discr->fillFromAnalytic(loc,nbOfComp,func); } /*! - * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic. - * See MEDCouplingMesh::fillFromAnalytic method doc to have more details. - * The main difference is that the field as been started to be constructed here. - * An exception is thrown if no underlying mesh is set before the call of this method. + * Creates data array(s) of \a this field by using a function for value generation.
+ * The function is applied to coordinates of value location points. For example, if + * \a this field is on cells, the function is applied to cell barycenters. + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * The function can include arbitrary named variables + * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of + * variables are sorted in \b alphabetical \b order to associate a variable name with a + * component. For example, in the expression "2*x+z", "x" stands for the component #0 + * and "z" stands for the component #1 (\b not #2)!
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, coordinates of a 3D point are (1.,3.,7.), then + * - "2*x + z" produces (5.,5.,5.,5.) + * - "2*x + 0*y + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is used to compute a field value basing on coordinates of value + * location point. For example, if \a this field is on cells, the function + * is applied to cell barycenters. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".
+ * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". */ void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic !"); MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); _time_discr->fillFromAnalytic(loc,nbOfComp,func); } /*! - * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic2. - * See MEDCouplingMesh::fillFromAnalytic method doc to have more details. - * The main difference is that the field as been started to be constructed here. - * An exception is throw if no underlying mesh is set before the call of this method. + * Creates data array(s) of \a this field by using a function for value generation.
+ * The function is applied to coordinates of value location points. For example, if + * \a this field is on cells, the function is applied to cell barycenters.
+ * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) "fillFromAnalytic()" + * by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a variable name corresponding to a component is retrieved from + * a corresponding node coordinates array (where it is set via + * DataArrayDouble::setInfoOnComponent()).
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, names of spatial components are "x", "y" and "z", + * coordinates of a 3D point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is used to compute a field value basing on coordinates of value + * location point. For example, if \a this field is on cells, the function + * is applied to cell barycenters. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".
+ * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". */ void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic2 !"); MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); _time_discr->fillFromAnalytic2(loc,nbOfComp,func); } /*! - * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic3. - * See MEDCouplingMesh::fillFromAnalytic method doc to have more details. - * The main difference is that the field as been started to be constructed here. - * An exception is thrown if no underlying mesh is set before the call of this method. + * Creates data array(s) of \a this field by using a function for value generation.
+ * The function is applied to coordinates of value location points. For example, if + * \a this field is on cells, the function is applied to cell barycenters.
+ * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) "fillFromAnalytic()" + * by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a component index of a variable is defined by a + * rank of the variable within the input array \a varsOrder.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. + * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, names of + * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a + * 3D point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is used to compute a field value basing on coordinates of value + * location point. For example, if \a this field is on cells, the function + * is applied to cell barycenters. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".
+ * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". */ void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic2 : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform fillFromAnalytic3 !"); MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func); } /*! - * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr. - * If '*func' returns false during one evaluation an exception will be thrown. + * Modifies values of \a this field by applying a C function to each tuple of all + * data arrays. + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a field value basing on a current field value. + * \throw If \a func returns \c false. + * + * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example". */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) { @@ -961,30 +1533,94 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) } /*! - * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to - * ParaMEDMEM::MEDCouplingFieldDouble::operator=. + * Fill \a this field with a given value.
+ * This method is a specialization of other overloaded methods. When \a nbOfComp == 1 + * this method is equivalent to ParaMEDMEM::MEDCouplingFieldDouble::operator=(). + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] val - the value to assign to every atomic value of \a this field. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * + * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".
+ * \ref py_mcfielddouble_applyFunc_val "Here is a Python example". */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform applyFunc !"); int nbOfTuple=_type->getNumberOfTuples(_mesh); _time_discr->setUniformValue(nbOfTuple,nbOfComp,val); } /*! - * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. - * If '*func' fails in evaluation during one evaluation an exception will be thrown. - * The field will contain 'nbOfComp' components after the call. + * Modifies values of \a this field by applying a function to each tuple of all + * data arrays. + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * The function can include arbitrary named variables + * (e.g. "x","y" or "va44") to refer to components of a field value. Names of + * variables are sorted in \b alphabetical \b order to associate a variable name with a + * component. For example, in the expression "2*x+z", "x" stands for the component #0 + * and "z" stands for the component #1 (\b not #2)!
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then + * - "2*x + z" produces (5.,5.,5.,5.) + * - "2*x + 0*y + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a field value basing on a current field value. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".
+ * \ref py_mcfielddouble_applyFunc "Here is a Python example". */ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) { _time_discr->applyFunc(nbOfComp,func); } + /*! - * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here components info are used to determine variables position in 'func'. - * If there is vars detected in 'func' that is not in an info on components an exception will be thrown. + * Modifies values of \a this field by applying a function to each tuple of all + * data arrays. + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) "applyFunc()" + * by the way how variable + * names, used in the function, are associated with components of field values; + * here, a variable name corresponding to a component is retrieved from + * component information of an array (where it is set via + * DataArrayDouble::setInfoOnComponent()).
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, components of a field value are (1.,3.,7.), then + * - "2*x + z" produces (5.,5.,5.,5.) + * - "2*x + 0*y + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a new field value basing on a current field value. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".
+ * \ref py_mcfielddouble_applyFunc2 "Here is a Python example". */ void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) { @@ -992,8 +1628,36 @@ void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const char *func) throw(IN } /*! - * This method is equivalent to MEDCouplingFieldDouble::applyFunc, except that here 'varsOrder' is used to determine variables position in 'func'. - * If there is vars detected in 'func' that is not in 'varsOrder' an exception will be thrown. + * Modifies values of \a this field by applying a function to each tuple of all + * data arrays. + * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const char *func) "applyFunc()" + * by the way how variable + * names, used in the function, are associated with components of field values; + * here, a component index of a variable is defined by a + * rank of the variable within the input array \a varsOrder.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. + * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, names of + * components are given in \a varsOrder: ["x", "y","z"], components of a + * 3D vector are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) + * + * \param [in] nbOfComp - the number of components for \a this field to have. + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a new field value basing on a current field value. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".
+ * \ref py_mcfielddouble_applyFunc3 "Here is a Python example". */ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception) { @@ -1001,9 +1665,29 @@ void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector + * The function can include **only one** arbitrary named variable + * (e.g. "x","y" or "va44") to refer to a field atomic value.
+ * In a general case, a value resulting from the function evaluation is assigned to + * a single field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, components of a field value are (1.,3.,7.), then + * - "2*x - 1" produces (1.,5.,13.) + * - "2*x*IVec + (x+3)*KVec" produces (2.,0.,10.) + * - "2*x*IVec + (x+3)*KVec + 1" produces (3.,1.,11.) + * + * \param [in] func - the function used to compute values of \a this field. + * This function is to compute a field value basing on a current field value. + * \throw If computing \a func fails. + * + * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".
+ * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". */ void MEDCouplingFieldDouble::applyFunc(const char *func) throw(INTERP_KERNEL::Exception) { @@ -1031,9 +1715,10 @@ void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERN } /*! - * This method makes the assumption that the default array has been set before. - * If not an exception will be sent. - * If default array set, the number of components will be sent. + * Returns number of components in the data array. For more info on the data arrays, + * see \ref MEDCouplingArrayPage. + * \return int - the number of components in the data array. + * \throw If the data array is not set. */ int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception) { @@ -1043,23 +1728,38 @@ int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::E } /*! - * This method makes the assumption that _mesh has be set before the call of this method and description of gauss - * localizations in case of Gauss field. If not an exception will sent. - * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is - * \b not aware of the presence of the default array. - * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that ! + * Returns number of tuples in \a this field, that depends on + * - the number of entities in the underlying mesh + * - \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field (e.g. number + * of Gauss points if \a this->getTypeOfField() == + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT"). + * + * The returned value does **not depend** on the number of tuples in the data array + * (which has to be equal to the returned value), \b contrary to + * getNumberOfComponents() and getNumberOfValues() that retrieve information from the + * data array. + * \warning No checkCoherency() is done here. + * For more info on the data arrays, see \ref MEDCouplingArrayPage. + * \return int - the number of tuples. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the spatial discretization is not fully defined. */ int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getNumberOfTuples !"); return _type->getNumberOfTuples(_mesh); } /*! - * This method makes the assumption that the default array has been set before. - * If not an exception will be sent. - * If default array set, the number of values present in the default array will be sent. + * Returns number of atomic double values in the data array of \a this field. + * For more info on the data arrays, see \ref MEDCouplingArrayPage. + * \return int - (number of tuples) * (number of components) of the + * data array. + * \throw If the data array is not set. */ int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception) { @@ -1068,33 +1768,106 @@ int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Excep return getArray()->getNbOfElems(); } +/*! + * Sets own modification time by the most recently modified element of data (the mesh, + * the data array etc). For more info, see \ref MEDCouplingTimeLabelPage. + */ void MEDCouplingFieldDouble::updateTime() const { MEDCouplingField::updateTime(); updateTimeWith(*_time_discr); } +std::size_t MEDCouplingFieldDouble::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_time_discr) + ret+=_time_discr->getHeapMemorySize(); + return MEDCouplingField::getHeapMemorySize()+ret; +} + +/*! + * Sets \ref NatureOfField. + * \param [in] nat - an item of enum ParaMEDMEM::NatureOfField. + */ void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception) { MEDCouplingField::setNature(nat); - _type->checkCompatibilityWithNature(nat); + if(_type) + _type->checkCompatibilityWithNature(nat); } +/*! + * This method synchronizes time information (time, iteration, order, time unit) regarding the information in \c this->_mesh. + * \throw If no mesh is set in this. Or if \a this is not compatible with time setting (typically NO_TIME) + */ +void MEDCouplingFieldDouble::synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::synchronizeTimeWithMesh : no mesh set in this !"); + int it=-1,ordr=-1; + double val=_mesh->getTime(it,ordr); + std::string timeUnit(_mesh->getTimeUnit()); + setTime(val,it,ordr); + setTimeUnit(timeUnit.c_str()); +} + +/*! + * Returns a value of \a this field of type either + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". + * \param [in] cellId - an id of cell of interest. + * \param [in] nodeIdInCell - a node index within the cell. + * \param [in] compoId - an index of component. + * \return double - the field value corresponding to the specified parameters. + * \throw If the data array is not set. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If \a this field if of type other than + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" or + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". + */ double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getIJK !"); return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId); } +/*! + * Sets the data array. + * \param [in] array - the data array holding values of \a this field. It's size + * should correspond to the mesh and + * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field + * (see getNumberOfTuples()), but this size is not checked here. + */ void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) { _time_discr->setArray(array,this); } +/*! + * Sets the data array holding values corresponding to an end of a time interval + * for which \a this field is defined. + * \param [in] array - the data array holding values of \a this field. It's size + * should correspond to the mesh and + * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field + * (see getNumberOfTuples()), but this size is not checked here. + */ void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) { _time_discr->setEndArray(array,this); } +/*! + * Sets all data arrays needed to define the field values. + * \param [in] arrs - a vector of DataArrayDouble's holding values of \a this + * field. Size of each array should correspond to the mesh and + * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field + * (see getNumberOfTuples()), but this size is not checked here. + * \throw If number of arrays in \a arrs does not correspond to type of + * \ref MEDCouplingTemporalDisc "temporal discretization" of \a this field. + */ void MEDCouplingFieldDouble::setArrays(const std::vector& arrs) throw(INTERP_KERNEL::Exception) { _time_discr->setArrays(arrs,this); @@ -1116,6 +1889,8 @@ void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); tinyInfo.clear(); tinyInfo.push_back((int)_type->getEnum()); tinyInfo.push_back((int)_time_discr->getEnum()); @@ -1133,6 +1908,8 @@ void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector */ void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfo) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); tinyInfo.clear(); _time_discr->getTinySerializationDbleInformation(tinyInfo); std::vector tinyInfo2; @@ -1150,6 +1927,8 @@ void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); dataInt=0; std::vector tinyInfoITmp(tinyInfoI); int sz=tinyInfoITmp.back(); @@ -1163,6 +1942,8 @@ void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& ti void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); // std::vector tmp(tinyInfoD); @@ -1186,55 +1967,116 @@ void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyI */ void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform serialize !"); _time_discr->getArrays(arrays); _type->getSerializationIntArray(dataInt); } /*! - * This method tries to to change the mesh support of \a this following the parameter 'levOfCheck' and 'prec'. - * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job. - * If this->_mesh is not defined or other an exeption will be throw. + * Tries to set an \a other mesh as the support of \a this field. An attempt fails, if + * a current and the \a other meshes are different with use of specified equality + * criteria, and then an exception is thrown. + * \param [in] other - the mesh to use as the field support if this mesh can be + * considered equal to the current mesh. + * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For + * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which + * is used for mesh comparison. + * \param [in] precOnMesh - a precision used to compare nodes of the two meshes. + * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith(). + * \param [in] eps - a precision used at node renumbering (if needed) to compare field + * values at merged nodes. If the values differ more than \a eps, an + * exception is thrown. + * \throw If the mesh is not set. + * \throw If \a other == NULL. + * \throw If any of the meshes is not well defined. + * \throw If the two meshes do not match. + * \throw If field values at merged nodes (if any) deffer more than \a eps. + * + * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".
+ * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". */ -void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) throw(INTERP_KERNEL::Exception) { if(_mesh==0 || other==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !"); DataArrayInt *cellCor=0,*nodeCor=0; - other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor); + other->checkGeoEquivalWith(_mesh,levOfCheck,precOnMesh,cellCor,nodeCor); MEDCouplingAutoRefCountObjectPtr cellCor2(cellCor),nodeCor2(nodeCor); if(cellCor) renumberCellsWithoutMesh(cellCor->getConstPointer(),false); if(nodeCor) - renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes()); + renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); setMesh(const_cast(other)); } /*! - * This method is an extension of MEDCouplingFieldDouble::operator-=. It allows a user to operate a difference of 2 fields (\a this and 'f') even if they do not share same meshes. - * No interpolation will be done here only an analyze of two underlying mesh will be done to see if the meshes are geometrically equivalent. If yes, the eventual renumbering will be done and operator-= applyed after. - * This method requires that 'f' and \a this are coherent (check coherency) and that 'f' and \a this would be coherent for a merge. - * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. + * Subtracts another field from \a this one in case when the two fields have different + * supporting meshes. The subtraction is performed provided that the tho meshes can be + * considered equal with use of specified equality criteria, else an exception is thrown. + * If the meshes match, the mesh of \a f is set to \a this field (\a this is permuted if + * necessary) and field values are subtracted. No interpolation is done here, only an + * analysis of two underlying mesh is done to see if the meshes are geometrically + * equivalent.
+ * The job of this method consists in calling + * \a this->changeUnderlyingMesh() with \a f->getMesh() as the first parameter, and then + * \a this -= \a f.
+ * This method requires that \a f and \a this are coherent (checkCoherency()) and that \a f + * and \a this are coherent for a merge.
+ * "DM" in the method name stands for "different meshes". + * \param [in] f - the field to subtract from this. + * \param [in] levOfCheck - defines equality criteria used for mesh comparison. For + * it's meaning explanation, see MEDCouplingMesh::checkGeoEquivalWith() which + * is used for mesh comparison. + * \param [in] precOnMesh - a precision used to compare nodes of the two meshes. + * It is used as \a prec parameter of MEDCouplingMesh::checkGeoEquivalWith(). + * \param [in] eps - a precision used at node renumbering (if needed) to compare field + * values at merged nodes. If the values differ more than \a eps, an + * exception is thrown. + * \throw If \a f == NULL. + * \throw If any of the meshes is not set or is not well defined. + * \throw If the two meshes do not match. + * \throw If the two fields are not coherent for merge. + * \throw If field values at merged nodes (if any) deffer more than \a eps. + * + * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".
+ * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". + * \sa changeUnderlyingMesh(). */ -void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) throw(INTERP_KERNEL::Exception) { checkCoherency(); + if(!f) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); f->checkCoherency(); if(!areCompatibleForMerge(f)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !"); - changeUnderlyingMesh(f->getMesh(),levOfCheck,prec); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); + changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); operator-=(*f); } /*! - * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change. - * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging. - * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown. + * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the + * underlying mesh is replaced by a new mesh instance where the coincident nodes are merged. + * \param [in] eps - a precision used to compare nodes of the two meshes. + * \param [in] epsOnVals - a precision used to compare field + * values at merged nodes. If the values differ more than \a epsOnVals, an + * exception is thrown. + * \return bool - \c true if some nodes have been merged and hence \a this field lies + * on another mesh. + * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. + * \throw If the mesh is not well defined. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the data array is not set. + * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. */ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes !"); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); bool ret; int ret2; @@ -1251,15 +2093,29 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTE } /*! - * Merge nodes with (barycenter computation) of underlying mesh. In case of some node will be merged the underlying mesh instance will change. - * The first 'eps' stands for geometric approximation. The second 'epsOnVals' is for epsilon on values in case of node merging. - * If 2 nodes distant from less than 'eps' and with value different with more than 'epsOnVals' an exception will be thrown. + * Merges coincident nodes of the underlying mesh. If some nodes are coincident, the + * underlying mesh is replaced by a new mesh instance where the coincident nodes are + * merged.
+ * In contrast to mergeNodes(), location of merged nodes is changed to be at their barycenter. + * \param [in] eps - a precision used to compare nodes of the two meshes. + * \param [in] epsOnVals - a precision used to compare field + * values at merged nodes. If the values differ more than \a epsOnVals, an + * exception is thrown. + * \return bool - \c true if some nodes have been merged and hence \a this field lies + * on another mesh. + * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. + * \throw If the mesh is not well defined. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the data array is not set. + * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. */ bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INTERP_KERNEL::Exception) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform mergeNodes2 !"); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); bool ret; int ret2; @@ -1276,15 +2132,27 @@ bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INT } /*! - * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet. - * If some nodes have disappeared true is returned. - * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ. + * Removes from the underlying mesh nodes not used in any cell. If some nodes are + * removed, the underlying mesh is replaced by a new mesh instance where the unused + * nodes are removed.
+ * \param [in] epsOnVals - a precision used to compare field + * values at merged nodes. If the values differ more than \a epsOnVals, an + * exception is thrown. + * \return bool - \c true if some nodes have been removed and hence \a this field lies + * on another mesh. + * \throw If the mesh is of type not inheriting from MEDCouplingPointSet. + * \throw If the mesh is not well defined. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the data array is not set. + * \throw If field values at merged nodes (if any) deffer more than \a epsOnVals. */ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Exception) { const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipCoords !"); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); int oldNbOfNodes=meshC2->getNumberOfNodes(); MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipCoordsTraducer(); @@ -1302,15 +2170,30 @@ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Ex } /*! - * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh. - * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method. - * 'epsOnVals' stands for epsilon in case of merge of cells. This value is used as tolerance in case the corresponding values differ. + * Removes duplicates of cells from the understanding mesh. If some cells are + * removed, the underlying mesh is replaced by a new mesh instance where the cells + * duplicates are removed.
+ * \param [in] compType - specifies a cell comparison technique. Meaning of its + * valid values [0,1,2] is explained in the description of + * MEDCouplingUMesh::zipConnectivityTraducer() which is called by this method. + * \param [in] epsOnVals - a precision used to compare field + * values at merged cells. If the values differ more than \a epsOnVals, an + * exception is thrown. + * \return bool - \c true if some cells have been removed and hence \a this field lies + * on another mesh. + * \throw If the mesh is not an instance of MEDCouplingUMesh. + * \throw If the mesh is not well defined. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the data array is not set. + * \throw If field values at merged cells (if any) deffer more than \a epsOnVals. */ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) throw(INTERP_KERNEL::Exception) { const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); if(!meshC) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipConnectivity : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform zipConnectivity !"); MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingUMesh *)meshC->deepCpy()); int oldNbOfCells=meshC2->getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipConnectivityTraducer(compType); @@ -1362,15 +2245,30 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *ori } } ret->setArrays(newArr); - ret->incrRef(); return ret; + return ret.retn(); } /*! - * This method applyies ParaMEDMEM::MEDCouplingUMesh::simplexize on 'this->_mesh'. - * The semantic of 'policy' is given in ParaMEDMEM::MEDCouplingUMesh::simplexize method. + * Divides every cell of the underlying mesh into simplices (triangles in 2D and + * tetrahedra in 3D). If some cells are divided, the underlying mesh is replaced by a new + * mesh instance containing the simplices.
+ * \param [in] policy - specifies a pattern used for splitting. For its description, see + * MEDCouplingUMesh::simplexize(). + * \return bool - \c true if some cells have been divided and hence \a this field lies + * on another mesh. + * \throw If \a policy has an invalid value. For valid values, see the description of + * MEDCouplingUMesh::simplexize(). + * \throw If MEDCouplingMesh::simplexize() is not applicable to the underlying mesh. + * \throw If the mesh is not well defined. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the data array is not set. */ bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Exception) { + if(!_mesh) + throw INTERP_KERNEL::Exception("No underlying mesh on this field to perform simplexize !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform simplexize !"); int oldNbOfCells=_mesh->getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr meshC2(_mesh->deepCpy()); MEDCouplingAutoRefCountObjectPtr arr=meshC2->simplexize(policy); @@ -1386,145 +2284,340 @@ bool MEDCouplingFieldDouble::simplexize(int policy) throw(INTERP_KERNEL::Excepti return true; } +/*! + * Creates a new MEDCouplingFieldDouble filled with the doubly contracted product of + * every tensor of \a this 6-componental field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose + * each tuple is calculated from the tuple (t) of \a this field as + * follows: \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. + * This new field lies on the same mesh as \a this one. The caller is to delete + * this field using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 6. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform doublyContractedProduct !"); MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("DoublyContractedProduct"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble filled with the determinant of a square + * matrix defined by every tuple of \a this field, having either 4, 6 or 9 components. + * The case of 6 components corresponds to that of the upper triangular matrix. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, whose + * each tuple is the determinant of matrix of the corresponding tuple of \a this + * field. This new field lies on the same mesh as \a this one. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform determinant !"); MEDCouplingTimeDiscretization *td=_time_discr->determinant(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("Determinant"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } + +/*! + * Creates a new MEDCouplingFieldDouble with 3 components filled with 3 eigenvalues of + * an upper triangular matrix defined by every tuple of \a this 6-componental field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having 3 components, whose each tuple contains the eigenvalues of the matrix of + * corresponding tuple of \a this field. This new field lies on the same mesh as + * \a this one. The caller is to delete this field using decrRef() as it is no + * more needed. + * \throw If \a this->getNumberOfComponents() != 6. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenValues !"); MEDCouplingTimeDiscretization *td=_time_discr->eigenValues(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("EigenValues"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble with 9 components filled with 3 eigenvectors of + * an upper triangular matrix defined by every tuple of \a this 6-componental field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having 9 components, whose each tuple contains the eigenvectors of the matrix of + * corresponding tuple of \a this field. This new field lies on the same mesh as + * \a this one. The caller is to delete this field using decrRef() as it is no + * more needed. + * \throw If \a this->getNumberOfComponents() != 6. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform eigenVectors !"); MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("EigenVectors"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble filled with the inverse matrix of + * a matrix defined by every tuple of \a this field having either 4, 6 or 9 + * components. The case of 6 components corresponds to that of the upper triangular + * matrix. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having the same number of components as \a this one, whose each tuple + * contains the inverse matrix of the matrix of corresponding tuple of \a this + * field. This new field lies on the same mesh as \a this one. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform inverse !"); MEDCouplingTimeDiscretization *td=_time_discr->inverse(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("Inversion"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble filled with the trace of + * a matrix defined by every tuple of \a this field having either 4, 6 or 9 + * components. The case of 6 components corresponds to that of the upper triangular + * matrix. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having 1 component, whose each tuple is the trace of the matrix of + * corresponding tuple of \a this field. + * This new field lies on the same mesh as \a this one. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform trace !"); MEDCouplingTimeDiscretization *td=_time_discr->trace(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("Trace"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble filled with the stress deviator tensor of + * a stress tensor defined by every tuple of \a this 6-componental field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having same number of components and tuples as \a this field, + * whose each tuple contains the stress deviator tensor of the stress tensor of + * corresponding tuple of \a this field. This new field lies on the same mesh as + * \a this one. The caller is to delete this field using decrRef() as it is no + * more needed. + * \throw If \a this->getNumberOfComponents() != 6. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform deviator !"); MEDCouplingTimeDiscretization *td=_time_discr->deviator(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Trace"); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Deviator"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble filled with the magnitude of + * every vector of \a this field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, + * having one component, whose each tuple is the magnitude of the vector + * of corresponding tuple of \a this field. This new field lies on the + * same mesh as \a this one. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform magnitude !"); MEDCouplingTimeDiscretization *td=_time_discr->magnitude(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName("Magnitude"); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Creates a new scalar MEDCouplingFieldDouble filled with the maximal value among + * values of every tuple of \a this field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * This new field lies on the same mesh as \a this one. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform maxPerTuple !"); MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple(); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); std::ostringstream oss; oss << "Max_" << getName(); ret->setName(oss.str().c_str()); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } +/*! + * Changes number of components in \a this field. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then + * each tuple is populated with \a dftValue to have \a newNbOfComp components. + * \param [in] newNbOfComp - number of components for the new field to have. + * \param [in] dftValue - value assigned to new values added to \a this field. + * \throw If \a this is not allocated. + */ void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception) { _time_discr->changeNbOfComponents(newNbOfComp,dftValue); } +/*! + * Creates a new MEDCouplingFieldDouble composed of selected components of \a this field. + * The new MEDCouplingFieldDouble has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result field + * can be either less, same or more than \a this->getNumberOfValues(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform keepSelectedComponents !"); MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds); td->copyTinyAttrFrom(*_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); ret->setName(getName()); ret->setMesh(getMesh()); - return ret; + return ret.retn(); } + +/*! + * Copy all components in a specified order from another field. + * The number of tuples in \a this and the other field can be different. + * \param [in] f - the field to copy data from. + * \param [in] compoIds - sequence of zero based indices of components, data of which is + * to be copied. + * \throw If the two fields have different number of data arrays. + * \throw If a data array is set in one of fields and is not set in the other. + * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + */ void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { _time_discr->setSelectedComponents(f->_time_discr,compoIds); } +/*! + * Sorts value within every tuple of \a this field. + * \param [in] asc - if \a true, the values are sorted in ascending order, else, + * in descending order. + * \throw If a data array is not allocated. + */ void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) { _time_discr->sortPerTuple(asc); } +/*! + * Creates a new MEDCouplingFieldDouble by concatenating two given fields. + * Values of + * the first field precede values of the second field within the result field. + * \param [in] f1 - the first field. + * \param [in] f2 - the second field. + * \return MEDCouplingFieldDouble * - the result field. It is a new instance of + * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() + * as it is no more needed. + * \throw If the fields are not compatible for the merge. + * \throw If \a f2->getMesh() == NULL. + * \throw If the spatial discretization of \a f1 is NULL. + * \throw If the time discretization of \a f1 is NULL. + * + * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
+ * \ref py_mcfielddouble_MergeFields "Here is a Python example". + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areCompatibleForMerge(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !"); const MEDCouplingMesh *m1=f1->getMesh(); const MEDCouplingMesh *m2=f2->getMesh(); - MEDCouplingMesh *m=m1->mergeMyselfWith(m2); + if(!m1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no underlying mesh of f1 !"); + if(!f1->_time_discr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !"); + if(!f1->_type) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no spatial discr of f1 !"); + MEDCouplingAutoRefCountObjectPtr m=m1->mergeMyselfWith(m2); MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(m); - m->decrRef(); ret->setName(f1->getName()); ret->setDescription(f1->getDescription()); - return ret; -} - -/*! - * This method returns a newly created field that is the union of all fields in input array 'a'. - * This method expects that 'a' is non empty. If not an exception will be thrown. - * If there is only one field in 'a' a deepCopy (except time information of mesh and field) of the unique field instance in 'a' will be returned. - * Generally speaking the first instance field in 'a' will be used to assign tiny attributes of returned field. + return ret.retn(); +} + +/*! + * Creates a new MEDCouplingFieldDouble by concatenating all given fields. + * Values of the *i*-th field precede values of the (*i*+1)-th field within the result. + * If there is only one field in \a a, a deepCopy() (except time information of mesh and + * field) of the field is returned. + * Generally speaking the first field in \a a is used to assign tiny attributes of the + * returned field. + * \param [in] a - a vector of fields (MEDCouplingFieldDouble) to concatenate. + * \return MEDCouplingFieldDouble * - the result field. It is a new instance of + * MEDCouplingFieldDouble. The caller is to delete this mesh using decrRef() + * as it is no more needed. + * \throw If \a a is empty. + * \throw If the fields are not compatible for the merge. + * \throw If \a a[ i ]->getMesh() == NULL. + * + * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
+ * \ref py_mcfielddouble_MergeFields "Here is a Python example". */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector& a) throw(INTERP_KERNEL::Exception) { @@ -1535,6 +2628,8 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector tds(a.size()); std::vector::const_iterator it=a.begin(); const MEDCouplingFieldDouble *ref=(*it++); + if(!ref) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !"); for(;it!=a.end();it++) if(!ref->areCompatibleForMerge(*it)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !"); @@ -1550,26 +2645,57 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vectorsetName(ms2[0]->getName()); m->setDescription(ms2[0]->getDescription()); MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); td->copyTinyAttrFrom(*(a[0]->_time_discr)); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); ret->setMesh(m); ret->setName(a[0]->getName()); ret->setDescription(a[0]->getDescription()); - return ret; + return ret.retn(); } +/*! + * Creates a new MEDCouplingFieldDouble by concatenating components of two given fields. + * The number of components in the result field is a sum of the number of components of + * given fields. The number of tuples in the result field is same as that of each of given + * arrays. + * Number of tuples in the given fields must be the same. + * \param [in] f1 - a field to include in the result field. + * \param [in] f2 - another field to include in the result field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the fields are not compatible for a meld (areCompatibleForMeld()). + * \throw If any of data arrays is not allocated. + * \throw If \a f1->getNumberOfTuples() != \a f2->getNumberOfTuples() + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { if(!f1->areCompatibleForMeld(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Returns a new MEDCouplingFieldDouble containing a dot product of two given fields, + * so that the i-th tuple of the result field is a sum of products of j-th components of + * i-th tuples of given fields (\f$ f_i = \sum_{j=1}^n f1_j * f2_j \f$). + * Number of tuples and components in the given fields must be the same. + * \param [in] f1 - a given field. + * \param [in] f2 - another given field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); @@ -1579,50 +2705,149 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingField return ret; } +/*! + * Returns a new MEDCouplingFieldDouble containing a cross product of two given fields, + * so that + * the i-th tuple of the result field is a 3D vector which is a cross + * product of two vectors defined by the i-th tuples of given fields. + * Number of tuples in the given fields must be the same. + * Number of components in the given fields must be 3. + * \param [in] f1 - a given field. + * \param [in] f2 - another given field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If \a f1->getNumberOfComponents() != 3 + * \throw If \a f2->getNumberOfComponents() != 3 + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Returns a new MEDCouplingFieldDouble containing maximal values of two given fields. + * Number of tuples and components in the given fields must be the same. + * \param [in] f1 - a field to compare values with another one. + * \param [in] f2 - another field to compare values with the first one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + * + * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
+ * \ref py_mcfielddouble_MaxFields "Here is a Python example". + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Returns a new MEDCouplingFieldDouble containing minimal values of two given fields. + * Number of tuples and components in the given fields must be the same. + * \param [in] f1 - a field to compare values with another one. + * \param [in] f2 - another field to compare values with the first one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + * + * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
+ * \ref py_mcfielddouble_MaxFields "Here is a Python example". + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Returns a copy of \a this field in which sign of all values is reversed. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble + * containing the same number of tuples and components as \a this field. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If a data array is not allocated. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::negate() const throw(INTERP_KERNEL::Exception) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform negate !"); + MEDCouplingTimeDiscretization *td=_time_discr->negate(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setMesh(getMesh()); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble containing sum values of corresponding values of + * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] + _f2_ [ i, j ] ). + * Number of tuples and components in the given fields must be the same. + * \param [in] f1 - a field to sum up. + * \param [in] f2 - another field to sum up. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Adds values of another MEDCouplingFieldDouble to values of \a this one + * ( _this_ [ i, j ] += _other_ [ i, j ] ) using DataArrayDouble::addEqual(). + * The two fields must have same number of tuples, components and same underlying mesh. + * \param [in] other - the field to add to \a this one. + * \return const MEDCouplingFieldDouble & - a reference to \a this field. + * \throw If \a other is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(&other)) @@ -1631,17 +2856,42 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCoupli return *this; } +/*! + * Returns a new MEDCouplingFieldDouble containing subtraction of corresponding values of + * two given fields ( _f_ [ i, j ] = _f1_ [ i, j ] - _f2_ [ i, j ] ). + * Number of tuples and components in the given fields must be the same. + * \param [in] f1 - a field to subtract from. + * \param [in] f2 - a field to subtract. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !"); if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Subtract values of another MEDCouplingFieldDouble from values of \a this one + * ( _this_ [ i, j ] -= _other_ [ i, j ] ) using DataArrayDouble::substractEqual(). + * The two fields must have same number of tuples, components and same underlying mesh. + * \param [in] other - the field to subtract from \a this one. + * \return const MEDCouplingFieldDouble & - a reference to \a this field. + * \throw If \a other is NULL. + * \throw If the fields are not strictly compatible (areStrictlyCompatible()), i.e. they + * differ not only in values. + */ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(&other)) @@ -1650,17 +2900,60 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCoupli return *this; } +/*! + * Returns a new MEDCouplingFieldDouble containing product values of + * two given fields. There are 2 valid cases. + * 1. The fields have same number of tuples and components. Then each value of + * the result field (_f_) is a product of the corresponding values of _f1_ and + * _f2_, i.e. _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, j ]. + * 2. The fields have same number of tuples and one field, say _f2_, has one + * component. Then + * _f_ [ i, j ] = _f1_ [ i, j ] * _f2_ [ i, 0 ]. + * + * The two fields must have same number of tuples and same underlying mesh. + * \param [in] f1 - a factor field. + * \param [in] f2 - another factor field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not compatible for production (areCompatibleForMul()), + * i.e. they differ not only in values and possibly number of components. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !"); if(!f1->areCompatibleForMul(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Multiply values of another MEDCouplingFieldDouble to values of \a this one + * using DataArrayDouble::multiplyEqual(). + * The two fields must have same number of tuples and same underlying mesh. + * There are 2 valid cases. + * 1. The fields have same number of components. Then each value of + * \a other is multiplied to the corresponding value of \a this field, i.e. + * _this_ [ i, j ] *= _other_ [ i, j ]. + * 2. The _other_ field has one component. Then + * _this_ [ i, j ] *= _other_ [ i, 0 ]. + * + * The two fields must have same number of tuples and same underlying mesh. + * \param [in] other - an field to multiply to \a this one. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If \a other is NULL. + * \throw If the fields are not strictly compatible for production + * (areCompatibleForMul()), + * i.e. they differ not only in values and possibly in number of components. + */ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areCompatibleForMul(&other)) @@ -1669,17 +2962,54 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCoupli return *this; } +/*! + * Returns a new MEDCouplingFieldDouble containing division of two given fields. + * There are 2 valid cases. + * 1. The fields have same number of tuples and components. Then each value of + * the result field (_f_) is a division of the corresponding values of \a f1 and + * \a f2, i.e. _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, j ]. + * 2. The fields have same number of tuples and _f2_ has one component. Then + * _f_ [ i, j ] = _f1_ [ i, j ] / _f2_ [ i, 0 ]. + * + * \param [in] f1 - a numerator field. + * \param [in] f2 - a denominator field. + * \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble. + * The caller is to delete this result field using decrRef() as it is no more + * needed. + * \throw If either \a f1 or \a f2 is NULL. + * \throw If the fields are not compatible for division (areCompatibleForDiv()), + * i.e. they differ not only in values and possibly in number of components. + */ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) { + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !"); if(!f1->areCompatibleForDiv(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); - return ret; + return ret.retn(); } +/*! + * Divide values of \a this field by values of another MEDCouplingFieldDouble + * using DataArrayDouble::divideEqual(). + * The two fields must have same number of tuples and same underlying mesh. + * There are 2 valid cases. + * 1. The fields have same number of components. Then each value of + * \a this field is divided by the corresponding value of \a other one, i.e. + * _this_ [ i, j ] /= _other_ [ i, j ]. + * 2. The \a other field has one component. Then + * _this_ [ i, j ] /= _other_ [ i, 0 ]. + * + * \warning No check of division by zero is performed! + * \param [in] other - an field to divide \a this one by. + * \throw If \a other is NULL. + * \throw If the fields are not compatible for division (areCompatibleForDiv()), + * i.e. they differ not only in values and possibly in number of components. + */ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) { if(!areCompatibleForDiv(&other)) @@ -1689,17 +3019,66 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCoupli } /*! - * This method writes the field series 'fs' in the VTK file 'fileName'. - * If 'fs' is empty no file is written. If fields lies on more than one mesh an exception will be thrown and no file will be written too. - * If the single mesh is empty an exception will be thrown. - * Finally there is a field in 'fs' with no name an exception will be thrown too. + * Directly called by MEDCouplingFieldDouble::operator^. + * + * \sa MEDCouplingFieldDouble::operator^ + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception) +{ + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !"); + if(!f1->areCompatibleForMul(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply PowFields on them !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret.retn(); +} + +/*! + * Directly call MEDCouplingFieldDouble::PowFields static method. + * + * \sa MEDCouplingFieldDouble::PowFields + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) +{ + return PowFields(this,&other); +} + +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception) +{ + if(!areCompatibleForDiv(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !"); + _time_discr->powEqual(other._time_discr); + return *this; +} + +/*! + * Writes the field series \a fs and the mesh the fields lie on in the VTK file \a fileName. + * If \a fs is empty no file is written. + * The result file is valid provided that no exception is thrown. + * \warning All the fields must be named and lie on the same non NULL mesh. + * \param [in] fileName - the name of a VTK file to write in. + * \param [in] fs - the fields to write. + * \throw If \a fs[ 0 ] == NULL. + * \throw If the fields lie not on the same mesh. + * \throw If the mesh is not set. + * \throw If any of the fields has no name. + * + * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".
+ * \ref py_mcfielddouble_WriteVTK "Here is a Python example". */ void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vector& fs) throw(INTERP_KERNEL::Exception) { if(fs.empty()) return; std::size_t nfs=fs.size(); + if(!fs[0]) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field is NULL !"); const MEDCouplingMesh *m=fs[0]->getMesh(); + if(!m) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : 1st instance of field lies on NULL mesh !"); for(std::size_t i=1;igetMesh()!=m) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are not lying on a same mesh ! Expected by VTK ! MEDCouplingFieldDouble::setMesh or MEDCouplingFieldDouble::changeUnderlyingMesh can help to that."); @@ -1723,3 +3102,44 @@ void MEDCouplingFieldDouble::WriteVTK(const char *fileName, const std::vectorwriteVTKAdvanced(fileName,coss.str(),noss.str()); } + +void MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCouplingFieldDouble C++ instance at " << this << ". Name : \"" << _name << "\"." << std::endl; + const char *nat=0; + try + { + nat=MEDCouplingNatureOfField::GetRepr(_nature); + stream << "Nature of field : " << nat << ".\n"; + } + catch(INTERP_KERNEL::Exception& e) + { } + const MEDCouplingFieldDiscretization *fd(_type); + if(!fd) + stream << "No spatial discretization set !"; + else + fd->reprQuickOverview(stream); + stream << std::endl; + if(!_mesh) + stream << "\nNo mesh support defined !"; + else + { + std::ostringstream oss; + _mesh->reprQuickOverview(oss); + std::string tmp(oss.str()); + stream << "\nMesh info : " << tmp.substr(0,tmp.find('\n')); + } + if(_time_discr) + { + const DataArrayDouble *arr=_time_discr->getArray(); + if(arr) + { + stream << "\n\nArray info : "; + arr->reprQuickOverview(stream); + } + else + { + stream << "\n\nNo data array set !"; + } + } +} diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 45a553b6b..61ee004f8 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -33,14 +33,17 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldDouble : public MEDCouplingField { public: - static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=NO_TIME); + static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); void setTimeUnit(const char *unit); const char *getTimeUnit() const; - void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); + void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); + void copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception); void copyTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); + void copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); std::string simpleRepr() const; std::string advancedRepr() const; + void writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception); bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception); bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; bool areCompatibleForMerge(const MEDCouplingField *other) const; @@ -50,11 +53,12 @@ namespace ParaMEDMEM bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); - void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception); + void renumberNodes(const int *old2NewBg, double eps=1e-15) throw(INTERP_KERNEL::Exception); void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception); DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *deepCpy() const; MEDCouplingFieldDouble *clone(bool recDeepCpy) const; MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; @@ -71,6 +75,7 @@ namespace ParaMEDMEM void setTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setTimeValue(val); } void setEndTimeValue(double val) throw(INTERP_KERNEL::Exception) { _time_discr->setEndTimeValue(val); } void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } + void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } @@ -95,7 +100,8 @@ namespace ParaMEDMEM double getAverageValue() const throw(INTERP_KERNEL::Exception); double norm2() const throw(INTERP_KERNEL::Exception); double normMax() const throw(INTERP_KERNEL::Exception); - double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception); + void getWeightedAverageValue(double *res, bool isWAbs=true) const throw(INTERP_KERNEL::Exception); + double getWeightedAverageValue(int compId, bool isWAbs=true) const throw(INTERP_KERNEL::Exception); double normL1(int compId) const throw(INTERP_KERNEL::Exception); void normL1(double *res) const throw(INTERP_KERNEL::Exception); double normL2(int compId) const throw(INTERP_KERNEL::Exception); @@ -106,7 +112,6 @@ namespace ParaMEDMEM void getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception); void getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception); DataArrayDouble *getValueOnMulti(const double *spaceLoc, int nbOfPoints) const throw(INTERP_KERNEL::Exception); - //! \b temporary void applyLin(double a, double b, int compoId); MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); @@ -125,6 +130,7 @@ namespace ParaMEDMEM int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); int getNumberOfValues() const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; // void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; @@ -133,8 +139,8 @@ namespace ParaMEDMEM void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); void serialize(DataArrayInt *&dataInt, std::vector& arrays) const; // - void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); - void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); + void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool mergeNodes2(double eps, double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); bool zipCoords(double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); @@ -165,6 +171,7 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return MaxFields(this,&other); } static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return MinFields(this,&other); } + MEDCouplingFieldDouble *negate() const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return AddFields(this,&other); } const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); @@ -177,13 +184,17 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return DivideFields(this,&other); } const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator^(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + const MEDCouplingFieldDouble &operator^=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); static void WriteVTK(const char *fileName, const std::vector& fs) throw(INTERP_KERNEL::Exception); public: const MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() const { return _time_discr; } MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() { return _time_discr; } + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); private: MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td); + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); ~MEDCouplingFieldDouble(); diff --git a/src/MEDCoupling/MEDCouplingFieldOverTime.cxx b/src/MEDCoupling/MEDCouplingFieldOverTime.cxx index 280c69a2d..01c48b7eb 100644 --- a/src/MEDCoupling/MEDCouplingFieldOverTime.cxx +++ b/src/MEDCoupling/MEDCouplingFieldOverTime.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/MEDCouplingFieldOverTime.hxx b/src/MEDCoupling/MEDCouplingFieldOverTime.hxx index f1daea33c..cc6a52b5f 100644 --- a/src/MEDCoupling/MEDCouplingFieldOverTime.hxx +++ b/src/MEDCoupling/MEDCouplingFieldOverTime.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx b/src/MEDCoupling/MEDCouplingFieldTemplate.cxx index 628ee6b72..235146889 100644 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx +++ b/src/MEDCoupling/MEDCouplingFieldTemplate.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ using namespace ParaMEDMEM; -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) +MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) { return new MEDCouplingFieldTemplate(f); } @@ -40,8 +40,9 @@ MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(TypeOfField type) return new MEDCouplingFieldTemplate(type); } -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception):MEDCouplingField(*f) +MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception):MEDCouplingField(f,false) { + forceTimeOfThis(f); checkCoherency(); } @@ -60,8 +61,11 @@ std::string MEDCouplingFieldTemplate::simpleRepr() const std::ostringstream ret; ret << "FieldTemplate with name : \"" << getName() << "\"\n"; ret << "Description of field is : \"" << getDescription() << "\"\n"; - ret << "FieldTemplate space discretization is : " << _type->getStringRepr() << "\n"; - ret << "FieldTemplate nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n"; + if(_type) + { ret << "FieldTemplate space discretization is : " << _type->getStringRepr() << "\n"; } + else + { ret << "FieldTemplate has no spatial discretization !\n"; } + ret << "FieldTemplate nature of field is : \"" << MEDCouplingNatureOfField::GetReprNoThrow(_nature) << "\"\n"; if(_mesh) ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); else @@ -76,6 +80,8 @@ std::string MEDCouplingFieldTemplate::advancedRepr() const void MEDCouplingFieldTemplate::getTinySerializationIntInformation(std::vector& tinyInfo) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationIntInformation !"); tinyInfo.clear(); tinyInfo.push_back((int)_type->getEnum()); tinyInfo.push_back((int)_nature); @@ -87,6 +93,8 @@ void MEDCouplingFieldTemplate::getTinySerializationIntInformation(std::vector& tinyInfo) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); tinyInfo.clear(); _type->getTinySerializationDbleInformation(tinyInfo); } @@ -100,6 +108,8 @@ void MEDCouplingFieldTemplate::getTinySerializationStrInformation(std::vector& tinyInfoI, DataArrayInt *&dataInt) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); dataInt=0; std::vector tinyInfoITmp(tinyInfoI.begin()+2,tinyInfoI.end()); _type->resizeForUnserialization(tinyInfoITmp,dataInt); @@ -107,6 +117,8 @@ void MEDCouplingFieldTemplate::resizeForUnserialization(const std::vector& void MEDCouplingFieldTemplate::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); _nature=(NatureOfField)tinyInfoI[1]; _type->finishUnserialization(tinyInfoD); _name=tinyInfoS[0]; @@ -118,3 +130,30 @@ void MEDCouplingFieldTemplate::serialize(DataArrayInt *&dataInt) const _type->getSerializationIntArray(dataInt); } +void MEDCouplingFieldTemplate::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "MEDCouplingFieldTemplate C++ instance at " << this << ". Name : \"" << _name << "\"." << std::endl; + const char *nat=0; + try + { + nat=MEDCouplingNatureOfField::GetRepr(_nature); + stream << "Nature of field template : " << nat << ".\n"; + } + catch(INTERP_KERNEL::Exception& e) + { } + const MEDCouplingFieldDiscretization *fd(_type); + if(!fd) + stream << "No spatial discretization set !"; + else + fd->reprQuickOverview(stream); + stream << std::endl; + if(!_mesh) + stream << "\nNo mesh support defined !"; + else + { + std::ostringstream oss; + _mesh->reprQuickOverview(oss); + std::string tmp(oss.str()); + stream << "\nMesh info : " << tmp.substr(0,tmp.find('\n')); + } +} diff --git a/src/MEDCoupling/MEDCouplingFieldTemplate.hxx b/src/MEDCoupling/MEDCouplingFieldTemplate.hxx index d93411ecb..3fb6cfa8a 100644 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.hxx +++ b/src/MEDCoupling/MEDCouplingFieldTemplate.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,7 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldTemplate : public MEDCouplingField { public: - static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldTemplate *New(TypeOfField type); std::string simpleRepr() const; std::string advancedRepr() const; @@ -43,8 +43,9 @@ namespace ParaMEDMEM void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); void serialize(DataArrayInt *&dataInt) const; // + void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); private: - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); MEDCouplingFieldTemplate(TypeOfField type); }; } diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx index 1b5df9b07..5906ffc8b 100644 --- a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx +++ b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -42,6 +42,23 @@ catch(INTERP_KERNEL::Exception& e) throw e; } +ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception) +try:_type(typ) +{ + INTERP_KERNEL::CellModel::GetCellModel(_type); +} +catch(INTERP_KERNEL::Exception& e) + { + _type=INTERP_KERNEL::NORM_ERROR; + throw e; + } + +void ParaMEDMEM::MEDCouplingGaussLocalization::setType(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception) +{ + INTERP_KERNEL::CellModel::GetCellModel(typ);//throws if not found. This is a check + _type=typ; +} + void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const throw(INTERP_KERNEL::Exception) { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); @@ -87,6 +104,15 @@ std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const return oss.str(); } +std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getHeapMemorySize() const +{ + std::size_t ret=0; + ret+=_ref_coord.capacity()*sizeof(double); + ret+=_gauss_coord.capacity()*sizeof(double); + ret+=_weight.capacity()*sizeof(double); + return ret; +} + bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const { if(_type!=other._type) @@ -194,6 +220,21 @@ void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, do _weight[gaussPtIdInCell]=newVal; } +void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoords(const std::vector& refCoo) throw(INTERP_KERNEL::Exception) +{ + _ref_coord=refCoo; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoords(const std::vector& gsCoo) throw(INTERP_KERNEL::Exception) +{ + _gauss_coord=gsCoo; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setWeights(const std::vector& w) throw(INTERP_KERNEL::Exception) +{ + _weight=w; +} + /*! * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo. */ diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.hxx b/src/MEDCoupling/MEDCouplingGaussLocalization.hxx index 49f843e7e..d8559ebd9 100644 --- a/src/MEDCoupling/MEDCouplingGaussLocalization.hxx +++ b/src/MEDCoupling/MEDCouplingGaussLocalization.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -36,11 +36,14 @@ namespace ParaMEDMEM public: MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception); + MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); INTERP_KERNEL::NormalizedCellType getType() const { return _type; } + void setType(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); int getNumberOfGaussPt() const { return (int)_weight.size(); } int getDimension() const; int getNumberOfPtsInRefCell() const; std::string getStringRepr() const; + std::size_t getHeapMemorySize() const; void checkCoherency() const throw(INTERP_KERNEL::Exception); bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; void pushTinySerializationIntInfo(std::vector& tinyInfo) const; @@ -56,6 +59,9 @@ namespace ParaMEDMEM void setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); void setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); void setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception); + void setRefCoords(const std::vector& refCoo) throw(INTERP_KERNEL::Exception); + void setGaussCoords(const std::vector& gsCoo) throw(INTERP_KERNEL::Exception); + void setWeights(const std::vector& w) throw(INTERP_KERNEL::Exception); // static MEDCouplingGaussLocalization BuildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData); static bool AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 9081b8ecb..3643c6bf8 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -36,10 +36,10 @@ typedef double (*MYFUNCPTR)(double); using namespace ParaMEDMEM; template -void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const +void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const { const double *coordsPtr=getConstPointer(); - BBTree myTree(bbox,0,0,nbNodes,prec/10); + BBTreePts myTree(bbox,0,0,nbNodes,prec); std::vector isDone(nbNodes); for(int i=0;ipushBackSilent(cI->back()+(int)commonNodes.size()+1); + c->pushBackSilent(i); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); } } } @@ -69,8 +69,8 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l } template -void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double *pos, int nbOfTuples, double eps, - std::vector& c, std::vector& cI) +void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, + DataArrayInt *c, DataArrayInt *cI) { for(int i=0;i& myTr std::vector commonNodes; for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) commonNodes.push_back(*it); - cI.push_back(cI.back()+(int)commonNodes.size()); - c.insert(c.end(),commonNodes.begin(),commonNodes.end()); + cI->pushBackSilent(cI->back()+(int)commonNodes.size()); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); } } +template +void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res) +{ + double distOpt(dist); + const double *p(pos); + int *r(res); + for(int i=0;i::max()) + { + distOpt=std::max(ret,1e-4); + *r=elem; + break; + } + else + { distOpt=2*distOpt; continue; } + } + } +} + +std::size_t DataArray::getHeapMemorySize() const +{ + std::size_t sz1=_name.capacity(); + std::size_t sz2=_info_on_compo.capacity(); + std::size_t sz3=0; + for(std::vector::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + sz3+=(*it).capacity(); + return sz1+sz2+sz3; +} + +/*! + * Sets the attribute \a _name of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \param [in] name - new array name + */ void DataArray::setName(const char *name) { _name=name; } +/*! + * Copies textual data from an \a other DataArray. The copied data are + * - the name attribute, + * - the information of components. + * + * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos". + * + * \param [in] other - another instance of DataArray to copy the textual data from. + * \throw If number of components of \a this array differs from that of the \a other. + */ void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception) { if(_info_on_compo.size()!=other._info_on_compo.size()) @@ -127,15 +176,9 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, cons setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str()); } -bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const +bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception) { std::ostringstream oss; - if(_nb_of_tuples!=other._nb_of_tuples) - { - oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples; - reason=oss.str(); - return false; - } if(_name!=other._name) { oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !"; @@ -156,13 +199,23 @@ bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reaso return true; } -bool DataArray::areInfoEquals(const DataArray& other) const +/*! + * Compares textual information of \a this DataArray with that of an \a other one. + * The compared data are + * - the name attribute, + * - the information of components. + * + * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos". + * \param [in] other - another instance of DataArray to compare the textual data of. + * \return bool - \a true if the textual information is same, \a false else. + */ +bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception) { std::string tmp; return areInfoEqualsIfNotWhy(other,tmp); } -void DataArray::reprWithoutNameStream(std::ostream& stream) const +void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { stream << "Number of components : "<< getNumberOfComponents() << "\n"; stream << "Info of these components : "; @@ -178,6 +231,12 @@ std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::E return ret.str(); } +/*! + * Sets information on all components. To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - a vector of strings. + * \throw If size of \a info differs from the number of components of \a this. + */ void DataArray::setInfoOnComponents(const std::vector& info) throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=(int)info.size()) @@ -188,7 +247,7 @@ void DataArray::setInfoOnComponents(const std::vector& info) throw( _info_on_compo=info; } -std::vector DataArray::getVarsOnComponent() const +std::vector DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception) { int nbOfCompo=(int)_info_on_compo.size(); std::vector ret(nbOfCompo); @@ -197,7 +256,7 @@ std::vector DataArray::getVarsOnComponent() const return ret; } -std::vector DataArray::getUnitsOnComponent() const +std::vector DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception) { int nbOfCompo=(int)_info_on_compo.size(); std::vector ret(nbOfCompo); @@ -206,6 +265,14 @@ std::vector DataArray::getUnitsOnComponent() const return ret; } +/*! + * Returns information on a component specified by an index. + * To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the information on \a i-th component. + * \throw If \a i is not a valid component index. + */ std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception) { if(i<(int)_info_on_compo.size() && i>=0) @@ -218,8 +285,16 @@ std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exce } /*! - * In the info part of i_th component this method returns the var part. - * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getVarOnComponent(0) will return "SIGXY" + * Returns the var part of the full information of the \a i-th component. + * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then + * \c getVarOnComponent(0) returns "SIGXY". + * If a unit part of information is not detected by presence of + * two square brackets, then the full information is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the var information, or the full info. + * \throw If \a i is not a valid component index. */ std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception) { @@ -235,8 +310,16 @@ std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Excep } /*! - * In the info part of i_th component this method returns the var part. - * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getUnitOnComponent(0) will return "N/m^2" + * Returns the unit part of the full information of the \a i-th component. + * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then + * \c getUnitOnComponent(0) returns " N/m^2". + * If a unit part of information is not detected by presence of + * two square brackets, then an empty string is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the unit information, if any, or "". + * \throw If \a i is not a valid component index. */ std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception) { @@ -251,6 +334,16 @@ std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exce } } +/*! + * Returns the var part of the full component information. + * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY". + * If a unit part of information is not detected by presence of + * two square brackets, then the whole \a info is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - the full component information. + * \return std::string - a string containing only var information, or the \a info. + */ std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception) { std::size_t p1=info.find_last_of('['); @@ -265,6 +358,16 @@ std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_ return info.substr(0,p3+1); } +/*! + * Returns the unit part of the full component information. + * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2". + * If a unit part of information is not detected by presence of + * two square brackets, then an empty string is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - the full component information. + * \return std::string - a string containing only unit information, if any, or "". + */ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception) { std::size_t p1=info.find_last_of('['); @@ -276,6 +379,15 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KER return info.substr(p1+1,p2-p1-1); } +/*! + * Sets information on a component specified by an index. + * To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \warning Don't pass NULL as \a info! + * \param [in] i - the index (zero based) of the component of interest. + * \param [in] info - the string containing the information. + * \throw If \a i is not a valid component index. + */ void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception) { if(i<(int)_info_on_compo.size() && i>=0) @@ -287,6 +399,32 @@ void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL: } } +/*! + * Sets information on all components. This method can change number of components + * at certain conditions; if the conditions are not respected, an exception is thrown. + * The number of components can be changed provided that \a this is not allocated. + * + * To know more on format of the component information see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - a vector of component infos. + * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated() + */ +void DataArray::setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception) +{ + if(getNumberOfComponents()!=(int)info.size()) + { + if(!isAllocated()) + _info_on_compo=info; + else + { + std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + _info_on_compo=info; +} + void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception) { if(getNumberOfTuples()!=nbOfTuples) @@ -305,7 +443,7 @@ void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTER } } -void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception) +void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception) { if(getNbOfElems()!=nbOfElems) { @@ -356,13 +494,13 @@ void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *m { if(value!=start || end!=start) { - std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected start " << start << " of range in [0," << value << "[ !"; + std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } if(end<0 || end>value) { - std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected start " << end << " of range in [0," << value << "[ !"; + std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -371,9 +509,48 @@ void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) thro { if(value<0 || value>ref) { - std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected a range in [0," << ref << "] having closing open parenthesis " << value << " !"; + std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, + * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh... + * + * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work. + * + * \param [in] start - the start of the input slice of the whole work to perform splitted into slices. + * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices. + * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices. + * \param [in] sliceId - the slice id considered + * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced) + * \param [out] startSlice - the start of the slice considered + * \param [out] stopSlice - the stop of the slice consided + * + * \throw If \a step == 0 + * \throw If \a nbOfSlices not > 0 + * \throw If \a sliceId not in [0,nbOfSlices) + */ +void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception) +{ + if(nbOfSlices<=0) + { + std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(sliceId<0 || sliceId>=nbOfSlices) + { + std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice"); + int minNbOfElemsPerSlice=nbElems/nbOfSlices; + startSlice=start+minNbOfElemsPerSlice*step*sliceId; + if(sliceId 0 !"; @@ -444,47 +623,47 @@ int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end return -1; } +/*! + * Returns a new instance of DataArrayDouble. The caller is to delete this array + * using decrRef() as it is no more needed. + */ DataArrayDouble *DataArrayDouble::New() { return new DataArrayDouble; } -bool DataArrayDouble::isAllocated() const +/*! + * Checks if raw data is allocated. Read more on the raw data + * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return bool - \a true if the raw data is allocated, \a false else. + */ +bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception) { return getConstPointer()!=0; } +/*! + * Checks if raw data is allocated and throws an exception if it is not the case. + * \throw If the raw data is not allocated. + */ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception) { if(!isAllocated()) throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } -/*! - * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' - * and if 'this' is not allocated it will change the number of components of 'this'. - * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method. - * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown. - */ -void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception) +std::size_t DataArrayDouble::getHeapMemorySize() const { - if(getNumberOfComponents()!=(int)info.size()) - { - if(!isAllocated()) - _info_on_compo=info; - else - { - std::ostringstream oss; oss << "DataArrayDouble::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - _info_on_compo=info; + std::size_t sz=_mem.getNbOfElemAllocated(); + sz*=sizeof(double); + return DataArray::getHeapMemorySize()+sz; } /*! - * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. - * If one or more conditions is not fulfilled an exception will be thrown. + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. */ double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception) { @@ -502,8 +681,9 @@ double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception) } /*! - * This method should be called on an allocated DataArrayDouble instance. If not an exception will be throw ! - * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned. + * Checks the number of tuples. + * \return bool - \a true if getNumberOfTuples() == 0, \a false else. + * \throw If \a this is not allocated. */ bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception) { @@ -511,12 +691,25 @@ bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception) return getNumberOfTuples()==0; } -DataArrayDouble *DataArrayDouble::deepCpy() const +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to + * delete this array using decrRef() as it is no more needed. + */ +DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception) { return new DataArrayDouble(*this); } -DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const +/*! + * Returns either a \a deep or \a shallow copy of this array. For more info see + * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. + * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. + * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ +DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception) { if(dCpy) return deepCpy(); @@ -527,21 +720,127 @@ DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const } } +/*! + * Copies all the data from another DataArrayDouble. For more info see + * \ref MEDCouplingArrayBasicsCopyDeepAssign. + * \param [in] other - another instance of DataArrayDouble to copy data from. + * \throw If the \a other is not allocated. + */ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception) { other.checkAllocated(); int nbOfTuples=other.getNumberOfTuples(); int nbOfComp=other.getNumberOfComponents(); allocIfNecessary(nbOfTuples,nbOfComp); - int nbOfElems=nbOfTuples*nbOfComp; + std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; double *pt=getPointer(); const double *ptI=other.getConstPointer(); - for(int i=0;igetNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -588,6 +912,15 @@ void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Checks if all values in \a this array are equal to \a val at precision \a eps. + * \param [in] val - value to check equality of array values to. + * \param [in] eps - precision to check the equality. + * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_), + * \a false else. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -604,45 +937,65 @@ bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNE return true; } +/*! + * Sorts values of the array. + * \param [in] asc - \a true means ascending order, \a false, descending. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception) { checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !"); _mem.sort(asc); + declareAsNew(); } +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) { checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::reverse : only supported with 'this' array with ONE component !"); - _mem.reverse(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); } /*! - * This method check that (Maths) array consistently INCREASING or DECREASING in value, - * with at least absolute difference value of |eps| at each step. - * if not an exception will be thrown. + * Checks that \a this array is consistently **increasing** or **decreasing** in value, + * with at least absolute difference value of |\a eps| at each step. + * If not an exception is thrown. + * \param [in] increasing - if \a true, the array values should be increasing. + * \param [in] eps - minimal absolute difference between the neighbor values at which + * the values are considered different. + * \throw If sequence of values is not strictly monotonic in agreement with \a + * increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ - void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) +void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) { - if(!isMonotonic(increasing, eps)) + if(!isMonotonic(increasing,eps)) { if (increasing) - { - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); - } + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); else - { - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); - } + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); } } /*! - * This method check that (Maths) array consistently INCREASING or DECREASING in value, - * with at least absolute difference value of |eps| at each step. + * Checks that \a this array is consistently **increasing** or **decreasing** in value, + * with at least absolute difference value of |\a eps| at each step. + * \param [in] increasing - if \a true, array values should be increasing. + * \param [in] eps - minimal absolute difference between the neighbor values at which + * the values are considered different. + * \return bool - \a true if values change in accordance with \a increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) { @@ -655,7 +1008,7 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTER return true; double ref=ptr[0]; double absEps=fabs(eps); - if (increasing) + if(increasing) { for(int i=1;i\n"; } -void DataArrayDouble::reprStream(std::ostream& stream) const +void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { stream << "Name of double array : \"" << _name << "\"\n"; reprWithoutNameStream(stream); } -void DataArrayDouble::reprZipStream(std::ostream& stream) const +void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { stream << "Name of double array : \"" << _name << "\"\n"; reprZipWithoutNameStream(stream); } -void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const +void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { DataArray::reprWithoutNameStream(stream); stream.precision(17); _mem.repr(getNumberOfComponents(),stream); } -void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const +void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { DataArray::reprWithoutNameStream(stream); stream.precision(17); _mem.reprZip(getNumberOfComponents(),stream); } -void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const +void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception) { int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); const double *data=getConstPointer(); @@ -745,38 +1103,130 @@ void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) c stream << varName << "->setName(\"" << getName() << "\");" << std::endl; } -bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const +/*! + * Method that gives a quick overvien of \a this for python. + */ +void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; + stream << "DataArrayDouble C++ instance at " << this << ". "; + if(isAllocated()) + { + int nbOfCompo=(int)_info_on_compo.size(); + if(nbOfCompo>=1) + { + int nbOfTuples=getNumberOfTuples(); + stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; + reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); + } + else + stream << "Number of components : 0."; + } + else + stream << "*** No data allocated ****"; +} + +void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception) +{ + const double *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbOfCompo=(int)_info_on_compo.size(); + std::ostringstream oss2; oss2 << "["; + oss2.precision(17); + std::string oss2Str(oss2.str()); + bool isFinished=true; + for(int i=0;i1) + { + oss2 << "("; + for(int j=0;jalloc(getNumberOfTuples(),getNumberOfComponents()); - int nbOfVals=getNbOfElems(); + std::size_t nbOfVals=getNbOfElems(); const double *src=getConstPointer(); int *dest=ret->getPointer(); std::copy(src,src+nbOfVals,dest); @@ -784,32 +1234,58 @@ DataArrayInt *DataArrayDouble::convertToIntArr() const return ret; } +/*! + * Returns a new DataArrayDouble holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. + * \warning Do not confuse this method with transpose()! + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception) { if(_mem.isNull()) throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !"); double *tab=_mem.fromNoInterlace(getNumberOfComponents()); DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); return ret; } +/*! + * Returns a new DataArrayDouble holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. + * \warning Do not confuse this method with transpose()! + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception) { if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !"); double *tab=_mem.toNoInterlace(getNumberOfComponents()); DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); return ret; } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + * Permutes values of \a this array as required by \a old2New array. The values are + * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains + * the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. */ -void DataArrayDouble::renumberInPlace(const int *old2New) +void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); double *tmp=new double[nbTuples*nbOfCompo]; @@ -822,11 +1298,18 @@ void DataArrayDouble::renumberInPlace(const int *old2New) } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. + * Permutes values of \a this array as required by \a new2Old array. The values are + * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains + * the same as in \this one. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ -void DataArrayDouble::renumberInPlaceR(const int *new2Old) +void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); double *tmp=new double[nbTuples*nbOfCompo]; @@ -839,14 +1322,23 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old) } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed renumberAndReduce. + * Returns a copy of \a this array with values permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. + * Number of tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ -DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const +DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbTuples,nbOfCompo); ret->copyStringInfoFrom(*this); const double *iptr=getConstPointer(); @@ -854,18 +1346,26 @@ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const for(int i=0;icopyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + * Returns a copy of \a this array with values permuted as required by \a new2Old array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of + * tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ -DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const +DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbTuples,nbOfCompo); ret->copyStringInfoFrom(*this); const double *iptr=getConstPointer(); @@ -873,20 +1373,28 @@ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const for(int i=0;icopyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * Idem DataArrayDouble::renumber method except that the number of tuples is reduced. - * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). - * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'+getNumberOfTuples()) the corresponding tuple is - * omitted. + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all + * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which + * \a old2New[ i ] is negative, is missing from the result array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old tuple and giving negative position for + * for i-th old tuple that should be omitted. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ -DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const +DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(newNbOfTuple,nbOfCompo); const double *iptr=getConstPointer(); double *optr=ret->getPointer(); @@ -897,16 +1405,29 @@ DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newN std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); } ret->copyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. - * This method is equivalent to DataArrayDouble::renumberAndReduce except that convention in input is new2old and \b not old2new. + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { - DataArrayDouble *ret=DataArrayDouble::New(); + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int nbComp=getNumberOfComponents(); ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); ret->copyStringInfoFrom(*this); @@ -916,14 +1437,31 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); ret->copyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * This method is equivalent to DataArrayDouble::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * This method is equivalent to selectByTupleId() except that it prevents coping data + * from behind the end of \a this array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). */ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int nbComp=getNumberOfComponents(); int oldNbOfTuples=getNumberOfTuples(); @@ -936,41 +1474,54 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons if(*w>=0 && *wgetNumberOfTuples) !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely. - * The convention is as python one. ['bg','end2') with steps of 'step'. - * Returns a newly created array. - * This method is a generalization of DataArrayDouble::substr. - * - * \sa DataArrayDouble::substr + * Returns a shorten copy of \a this array. The new DataArrayDouble contains every + * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th + * tuple. Indices of the selected tuples are the same as ones returned by the Python + * command \c range( \a bg, \a end2, \a step ). + * This method is equivalent to selectByTupleIdSafe() except that the input array is + * not constructed explicitly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] bg - index of the first tuple to copy from \a this array. + * \param [in] end2 - index of the tuple before which the tuples to copy are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \sa DataArrayDouble::substr. */ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); ret->alloc(newNbOfTuples,nbComp); double *pt=ret->getPointer(); const double *srcPt=getConstPointer()+bg*nbComp; for(int i=0;icopyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'. - * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception - * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too. + * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges + * of tuples specified by \a ranges parameter. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] ranges - std::vector of std::pair's each of which defines a range + * of tuples in [\c begin,\c end) format. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a end < \a begin. + * \throw If \a end > \a this->getNumberOfTuples(). + * \throw If \a this is not allocated. */ -DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) +DataArray *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) { checkAllocated(); int nbOfComp=getNumberOfComponents(); @@ -1019,20 +1570,27 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vectorgetPointer(); for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * 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. - * This method check that interval is valid regarding this, if not an exception will be thrown. - * This method is a specialization of method DataArrayDouble::selectByTupleId2. - * - * \sa DataArrayDouble::selectByTupleId2 + * Returns a shorten copy of \a this array. The new DataArrayDouble contains all + * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before + * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). + * This method is a specialization of selectByTupleId2(). + * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. + * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. + * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a tupleIdBg < 0. + * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). + \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). + * \sa DataArrayDouble::selectByTupleId2 */ DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbt=getNumberOfTuples(); if(tupleIdBg<0) throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !"); @@ -1047,22 +1605,30 @@ DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const th else trueEnd=nbt; int nbComp=getNumberOfComponents(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(trueEnd-tupleIdBg,nbComp); ret->copyStringInfoFrom(*this); std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret; + return ret.retn(); } /*! - * This method builds a new instance of DataArrayDouble (to deal with) that is reduction or an extension of 'this'. - * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. - * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then the result array is shorten as each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is + * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp + * components. + * \param [in] newNbOfComp - number of components for the new array to have. + * \param [in] dftValue - value assigned to new values added to the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception) { checkAllocated(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(getNumberOfTuples(),newNbOfComp); const double *oldc=getConstPointer(); double *nc=ret->getPointer(); @@ -1081,32 +1647,44 @@ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double d for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); ret->setName(getName().c_str()); - return ret; + return ret.retn(); } /*! - * Contrary to DataArrayDouble::changeNbOfComponents method this method is \b not const. The content - * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller. - * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown. - * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw ! - * This method erases all components info set before call ! + * Changes the number of components within \a this array so that its raw data **does + * not** change, instead splitting this data into tuples changes. + * \warning This method erases all (name and unit) component info set before! + * \param [in] newNbOfComp - number of components for \a this array to have. + * \throw If \a this is not allocated + * \throw If getNbOfElems() % \a newNbOfCompo != 0. + * \throw If \a newNbOfCompo is lower than 1. + * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). + * \warning This method erases all (name and unit) component info set before! */ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) { checkAllocated(); - int nbOfElems=getNbOfElems(); + if(newNbOfCompo<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !"); + std::size_t nbOfElems=getNbOfElems(); if(nbOfElems%newNbOfCompo!=0) throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !"); - _nb_of_tuples=nbOfElems/newNbOfCompo; + if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) + throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); _info_on_compo.clear(); _info_on_compo.resize(newNbOfCompo); declareAsNew(); } /*! - * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised. - * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of - * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method. + * Changes the number of components within \a this array to be equal to its number + * of tuples, and inversely its number of tuples to become equal to its number of + * components. So that its raw data **does not** change, instead splitting this + * data into tuples changes. + * \warning This method erases all (name and unit) component info set before! + * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! + * \throw If \a this is not allocated. + * \sa rearrange() */ void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception) { @@ -1115,7 +1693,22 @@ void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception) rearrange(nbOfTuples); } -DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +/*! + * Returns a copy of \a this array composed of selected components. + * The new DataArrayDouble has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result array + * can be either less, same or more than \a this->getNbOfElems(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + * + * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". + */ +DataArray *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) { checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); @@ -1135,15 +1728,20 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& for(int i=0;iincrRef(); - return ret; + return ret.retn(); } /*! - * This method melds the components of 'this' with components of 'other'. - * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' - * before the call and the number of components of 'other'. - * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + * Appends components of another array to components of \a this one, tuple by tuple. + * So that the number of tuples of \a this array remains the same and the number of + * components increases. + * \param [in] other - the DataArrayDouble to append to \a this one. + * \throw If \a this is not allocated. + * \throw If \a this and \a other arrays have different number of tuples. + * + * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". + * + * \ref py_mcdataarraydouble_meldwith "Here is a Python example". */ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { @@ -1154,7 +1752,7 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); int nbOfComp1=getNumberOfComponents(); int nbOfComp2=other->getNumberOfComponents(); - double *newArr=new double[nbOfTuples*(nbOfComp1+nbOfComp2)]; + double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double)); double *w=newArr; const double *inp1=getConstPointer(); const double *inp2=other->getConstPointer(); @@ -1163,7 +1761,7 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL w=std::copy(inp1,inp1+nbOfComp1,w); w=std::copy(inp2,inp2+nbOfComp2,w); } - useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); + useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); std::vector compIds(nbOfComp2); for(int i=0;igetNumberOfTuples()-1 gives the number of tuples groupes that are within distance 'prec'. - * comm->getNumberOfTuples()==commIndex->back() - * The returned pair of DataArrayInt instances ('comm','commIndex') is called Surjectived Format 2 \sa DataArrayInt::BuildNew2OldArrayFromSurjectiveFormat2. - * This format is more compact in surjective format because only all tuple ids not in 'comm' are remain unchanged. - * - * @param prec is an absolute precision. - * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. - * @param comm out parameter (not inout). Number of components is equal to 1. - * @param commIndex out parameter (not inout). Number of components is equal to 1. + * Searches for tuples coincident within \a prec tolerance. Each tuple is considered + * as coordinates of a point in getNumberOfComponents()-dimensional space. The + * distance is computed using norm2. + * + * Indices of coincident tuples are stored in output arrays. + * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2". + * + * This method is typically used by MEDCouplingPointSet::findCommonNodes() and + * MEDCouplingUMesh::mergeNodes(). + * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are + * considered not coincident. + * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident + * tuples have id strictly lower than \a limitTupleId then they are not returned. + * \param [out] comm - the array holding ids (== indices) of coincident tuples. + * \a comm->getNumberOfComponents() == 1. + * \a comm->getNumberOfTuples() == \a commIndex->back(). + * \param [out] commIndex - the array dividing all indices stored in \a comm into + * groups of (indices of) coincident tuples. Its every value is a tuple + * index where a next group of tuples begins. For example the second + * group of tuples in \a comm is described by following range of indices: + * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 + * gives the number of groups of coincident tuples. + * \throw If \a this is not allocated. + * \throw If the number of components is not in [1,2,3]. + * + * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". + * + * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". + * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(). */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception) { @@ -1193,30 +1807,24 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3."); int nbOfTuples=getNumberOfTuples(); - comm=DataArrayInt::New(); - commIndex=DataArrayInt::New(); // - MEDCouplingAutoRefCountObjectPtr bbox=computeBBoxPerTuple(prec); - // - std::vector c,cI(1); + MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); switch(nbOfCompo) { case 3: - findCommonTuplesAlg<3>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI); + findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; case 2: - findCommonTuplesAlg<2>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI); + findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; case 1: - findCommonTuplesAlg<1>(bbox->getConstPointer(),nbOfTuples,limitTupleId,prec,c,cI); + findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; default: throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !"); } - commIndex->alloc((int)cI.size(),1); - std::copy(cI.begin(),cI.end(),commIndex->getPointer()); - comm->alloc(cI.back(),1); - std::copy(c.begin(),c.end(),comm->getPointer()); + comm=c.retn(); + commIndex=cI.retn(); } /*! @@ -1244,37 +1852,147 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th *retPtr=val; } ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * This method returns a newly allocated object the user should deal with. - * This method works for arrays which have number of components into [1,2,3]. If not an exception will be thrown. - * This method returns the different values in 'this' using 'prec'. The different values are kept in the same - * order than 'this'. That is to say that returned DataArrayDouble instance is not systematically sorted. + * This methods returns the minimal distance between the two set of points \a this and \a other. + * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown. + * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3. * - * @param prec is an absolute precision. - * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. + * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance + * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance + * \return the minimal distance between the two set of points \a this and \a other. + * \sa DataArrayDouble::findClosestTupleId */ -DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception) +double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception) { - DataArrayInt *c0=0,*cI0=0; - findCommonTuples(prec,limitTupleId,c0,cI0); - MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); - int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples); - return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); + MEDCouplingAutoRefCountObjectPtr part1=findClosestTupleId(other); + int nbOfCompo(getNumberOfComponents()); + int otherNbTuples(other->getNumberOfTuples()); + const double *thisPt(begin()),*otherPt(other->begin()); + const int *part1Pt(part1->begin()); + double ret=std::numeric_limits::max(); + for(int i=0;igetNumberOfTuples() tuples and one components. + * \sa DataArrayDouble::minimalDistanceTo + */ +DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !"); + checkAllocated(); other->checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if(nbOfCompo!=other->getNumberOfComponents()) + { + std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo; + oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfTuples=other->getNumberOfTuples(); + int thisNbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); + double bounds[6]; + getMinMaxPerComponent(bounds); + switch(nbOfCompo) + { + case 3: + { + double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4])); + double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta); + double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.); + BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + case 2: + { + double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])); + double delta=std::max(xDelta,yDelta); + double characSize=sqrt(delta/(double)thisNbOfTuples); + BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + case 1: + { + double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples; + BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + default: + throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3."); + } + return ret.retn(); +} + +/*! + * Returns a copy of \a this array by excluding coincident tuples. Each tuple is + * considered as coordinates of a point in getNumberOfComponents()-dimensional + * space. The distance between tuples is computed using norm2. If several tuples are + * not far each from other than \a prec, only one of them remains in the result + * array. The order of tuples in the result array is same as in \a this one except + * that coincident tuples are excluded. + * \param [in] prec - minimal absolute distance between two tuples at which they are + * considered not coincident. + * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident + * tuples have id strictly lower than \a limitTupleId then they are not excluded. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If the number of components is not in [1,2,3]. + * + * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example". + */ +DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + DataArrayInt *c0=0,*cI0=0; + findCommonTuples(prec,limitTupleId,c0,cI0); + MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); + int newNbOfTuples=-1; + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); + return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); } +/*! + * Copy all components in a specified order from another DataArrayDouble. + * Both numerical and textual data is copied. The number of tuples in \a this and + * the other array can be different. + * \param [in] a - the array to copy data from. + * \param [in] compoIds - sequence of zero based indices of components, data of which is + * to be copied. + * \throw If \a a is NULL. + * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + * + * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example". + */ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { if(!a) throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !"); + checkAllocated(); copyPartOfStringInfoFrom2(compoIds,*a); std::size_t partOfCompoSz=compoIds.size(); int nbOfCompo=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); + int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); const double *ac=a->getConstPointer(); double *nc=getPointer(); for(int i=0;igetNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". */ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1299,18 +2047,55 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i int nbOfTuples=getNumberOfTuples(); DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg); - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - double *pt=getPointer()+bgTuples*nbComp+bgComp; + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } const double *srcPt=a->getConstPointer(); - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign values of \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - this parameter is checked only if the + * *mode of usage* is the first; if it is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() != (endComp - bgComp) . + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() != (endComp - bgComp). + * + * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". */ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1346,7 +2165,7 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu int newNbOfTuples=(int)std::distance(bgTuples,endTuples); int newNbOfComp=(int)std::distance(bgComp,endComp); bool assignTech=true; - if(a->getNbOfElems()==newNbOfTuples*newNbOfComp) + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) { if(strictCompoCompare) a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); @@ -1365,7 +2184,7 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); for(const int *z=bgComp;z!=endComp;z++,srcPt++) { - pt[(*w)*nbComp+(*z)]=*srcPt; + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; } } } @@ -1377,14 +2196,31 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); for(const int *z=bgComp;z!=endComp;z++,srcPt2++) { - pt[(*w)*nbComp+(*z)]=*srcPt2; + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; } } } } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples and components to assign to are defined by C arrays of indices. + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (\a pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * + * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". */ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception) { @@ -1398,13 +2234,53 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons for(const int *z=bgComp;z!=endComp;z++) { DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(*w)*nbComp+(*z)]=a; + pt[(std::size_t)(*w)*nbComp+(*z)]=a; } } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayDouble (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - this parameter is checked only in the first + * *mode of usage*; if \a strictCompoCompare is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". */ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1419,7 +2295,7 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); int newNbOfTuples=(int)std::distance(bgTuples,endTuples); bool assignTech=true; - if(a->getNbOfElems()==newNbOfTuples*newNbOfComp) + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) { if(strictCompoCompare) a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); @@ -1437,7 +2313,7 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu for(int j=0;j(pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". */ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -1470,18 +2367,128 @@ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, cons for(int j=0;jgetNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * */ -void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) +void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !"); + const char msg[]="DataArrayDouble::setPartOfValues4"; + checkAllocated(); + a->checkAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + int newNbOfComp=(int)std::distance(bgComp,endComp); + int nbComp=getNumberOfComponents(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + const double *srcPt=a->getConstPointer(); + double *pt=getPointer()+bgTuples*nbComp; + if(assignTech) + { + for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 2. + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * the corresponding (\a this or \a a) array. + */ +void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) +{ + if(!a || !tuplesSelec) throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !"); checkAllocated(); a->checkAllocated(); @@ -1518,15 +2525,35 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayDouble::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by \a tuplesSelec->getNumberOfTuples(). + * The tuples to copy are defined by values of a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a a array. */ -void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) +void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { - if(!a || !tuplesSelec) + if(!aBase || !tuplesSelec) throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayDouble *a=dynamic_cast(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !"); checkAllocated(); a->checkAllocated(); tuplesSelec->checkAllocated(); @@ -1558,15 +2585,37 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data } /*! - * 'this' and 'a' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayDouble::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to copy are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by number of tuples to copy. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a a. + * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). + * \throw If parameters specifying tuples to copy, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for the array \a a. */ -void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) +void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayDouble *a=dynamic_cast(aBase); if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArrayDouble is NULL !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !"); checkAllocated(); a->checkAllocated(); int nbOfComp=getNumberOfComponents(); @@ -1589,9 +2638,16 @@ void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const Dat } /*! - * This method is equivalent to DataArrayDouble::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()). - * If one of these check fails an INTERP_KERNEL::Exception will be thrown. - * So this method is safe but expensive if used to go through all data of \b this. + * Returns a value located at specified tuple and component. + * This method is equivalent to DataArrayDouble::getIJ() except that validity of + * parameters is checked. So this method is safe but expensive if used to go through + * all values of \a this. + * \param [in] tupleId - index of tuple of interest. + * \param [in] compoId - index of component of interest. + * \return double - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. + * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. */ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { @@ -1606,13 +2662,15 @@ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_K std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - return _mem[tupleId*((int)_info_on_compo.size())+compoId]; + return _mem[tupleId*_info_on_compo.size()+compoId]; } /*! - * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. - * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. - * And to finish this method works for arrays that have number of tuples >= 1. + * Returns the last value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. */ double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception) { @@ -1637,38 +2695,57 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar } } -void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) +/*! + * Sets a C array to be used as raw data of \a this. The previously set info + * of components is retained and re-sized. + * For more info see \ref MEDCouplingArraySteps1. + * \param [in] array - the C array to be used as raw data of \a this. + * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. + * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, + * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, + * \c free(\c array ) will be called. + * \param [in] nbOfTuple - new number of tuples in \a this. + * \param [in] nbOfCompo - new number of components in \a this. + */ +void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); + _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); declareAsNew(); } -void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) +void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); + _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo); declareAsNew(); } +/*! + * Checks if 0.0 value is present in \a this array. If it is the case, an exception + * is thrown. + * \throw If zero is found in \a this array. + */ void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception) { const double *tmp=getConstPointer(); - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); const double *where=std::find(tmp,tmp+nbOfElems,0.); if(where!=tmp+nbOfElems) throw INTERP_KERNEL::Exception("A value 0.0 have been detected !"); } /*! - * This method assume that \b this is allocated. If not an INTERP_KERNEL::Exception will be thrown. - * This method fills \b bounds params like that : \b bounds[0]=XMin, \b bounds[1]=XMax, \b bounds[2]=YMin, \b bounds[3]=YMax... - * Where X refers to component #0, and Y to component #1... - * This method set 2*this->getNumberOfComponents() elements in \b bounds, so it is up to the caller to allocated enough space before calling this method. - * - * @param [out] bounds array of size 2*this->getNumberOfComponents(). + * Computes minimal and maximal value in each component. An output array is filled + * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate + * enough memory before calling this method. + * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents(). + * It is filled as follows:
+ * \a bounds[0] = \c min_of_component_0
+ * \a bounds[1] = \c max_of_component_0
+ * \a bounds[2] = \c min_of_component_1
+ * \a bounds[3] = \c max_of_component_1
+ * ... */ void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception) { @@ -1723,8 +2800,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon; } } - bbox->incrRef(); - return bbox; + return bbox.retn(); } /*! @@ -1732,7 +2808,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps. * * \param [in] other a DataArrayDouble having same number of components than \a this. - * \param [in] eps absolute precision representing euclidian distance between 2 tuples behind which 2 tuples are considered equal. + * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal. * \param [out] c will contain the set of tuple ids in \a this that are equal to to the tuple ids in \a other contiguously. * \a cI allows to extract information in \a c. * \param [out] cI is an indirection array that allows to extract the data contained in \a c. @@ -1745,43 +2821,42 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw * * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues */ -void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception) +void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !"); - MEDCouplingAutoRefCountObjectPtr bbox=computeBBoxPerTuple(eps); + checkAllocated(); other->checkAllocated(); int nbOfCompo=getNumberOfComponents(); int otherNbOfCompo=other->getNumberOfComponents(); if(nbOfCompo!=otherNbOfCompo) throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !"); int nbOfTuplesOther=other->getNumberOfTuples(); - std::vector ret; - c.clear(); - cI.resize(1); cI[0]=0; + MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); switch(nbOfCompo) { case 3: { - BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps); + FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } case 2: { - BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps); + FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } case 1: { - BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10); - FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI); + BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps); + FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); break; } default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3."); } + c=cArr.retn(); cI=cIArr.retn(); } /*! @@ -1807,8 +2882,16 @@ void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::E } } +/*! + * Returns the maximal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the maximal value. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !"); int nbOfTuples=getNumberOfTuples(); @@ -1821,7 +2904,10 @@ double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exc } /*! - * Idem to DataArrayDouble::getMaxValue expect that here number of components can be >=1. + * Returns the maximal value within \a this array that is allowed to have more than + * one component. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. */ double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -1830,6 +2916,15 @@ double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exceptio return *loc; } +/*! + * Returns the maximal value and all its locations within \a this one-dimensional array. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the maximal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { int tmp; @@ -1839,8 +2934,16 @@ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP return ret; } +/*! + * Returns the minimal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the minimal value. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !"); int nbOfTuples=getNumberOfTuples(); @@ -1853,7 +2956,10 @@ double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exc } /*! - * Idem to DataArrayDouble::getMinValue expect that here number of components can be >=1. + * Returns the minimal value within \a this array that is allowed to have more than + * one component. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. */ double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -1862,6 +2968,15 @@ double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exceptio return *loc; } +/*! + * Returns the minimal value and all its locations within \a this one-dimensional array. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the minimal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { int tmp; @@ -1871,6 +2986,35 @@ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP return ret; } +/*! + * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value. + * This method only works for single component array. + * + * \return a value in [ 0, \c this->getNumberOfTuples() ) + * + * \throw If \a this is not allocated + * + */ +int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception) +{ + int ret=0; + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); + const double *vals=begin(); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;igetNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -1883,24 +3027,36 @@ double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) return ret/nbOfTuples; } +/*! + * Returns the Euclidean norm of the vector defined by \a this array. + * \return double - the value of the Euclidean norm, i.e. + * the square root of the inner product of vector. + * \throw If \a this is not allocated. + */ double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception) { checkAllocated(); double ret=0.; - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); const double *pt=getConstPointer(); - for(int i=0;iret) @@ -1909,6 +3065,13 @@ double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception) return ret; } +/*! + * Accumulates values of each component of \a this array. + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * by the caller, that is filled by this method with sum value for each + * component. + * \throw If \a this is not allocated. + */ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -1920,13 +3083,60 @@ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Excepti std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus()); } +/*! + * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and + * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown. + * + * + * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to + * \a tupleEnd. If not an exception will be thrown. + * + * \param [in] tupleBg start pointer (included) of input external tuple + * \param [in] tupleEnd end pointer (not included) of input external tuple + * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple + * \return the min distance. + * \sa MEDCouplingUMesh::distanceToPoint + */ +double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + if(nbComps!=(int)std::distance(tupleBg,tupleEnd)) + { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(nbTuple==0) + throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !"); + double ret0=std::numeric_limits::max(); + tupleId=-1; + const double *work=getConstPointer(); + for(int i=0;i=ret0) + continue; + else + { ret0=val; tupleId=i; } + } + return sqrt(ret0); +} + +/*! + * Accumulate values of the given component of \a this array. + * \param [in] compId - the index of the component of interest. + * \return double - a sum value of \a compId-th component. + * \throw If \a this is not allocated. + * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is + * not respected. + */ double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); const double *ptr=getConstPointer(); int nbTuple=getNumberOfTuples(); int nbComps=getNumberOfComponents(); - if(compId>=nbComps) + if(compId<0 || compId>=nbComps) throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !"); double ret=0.; for(int i=0;igetNumberOfTuples). + * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation. + * + * \param [in] bgOfIndex - begin (included) of the input index array. + * \param [in] endOfIndex - end (excluded) of the input index array. + * \return DataArrayDouble * - the new instance having the same number of components than \a this. + * + * \throw If bgOfIndex or end is NULL. + * \throw If input index array is not ascendingly sorted. + * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples). + * \throw If std::distance(bgOfIndex,endOfIndex)==0. + */ +DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception) +{ + if(!bgOfIndex || !endOfIndex) + throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !"); + checkAllocated(); + int nbCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + int sz=(int)std::distance(bgOfIndex,endOfIndex); + if(sz<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !"); + sz--; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo); + const int *w=bgOfIndex; + if(*w<0 || *w>=nbOfTuples) + throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); + const double *srcPt=begin()+(*w)*nbCompo; + double *tmp=ret->getPointer(); + for(int i=0;i=w[0]) + { + for(int j=w[0];j=0 && j()); + else + { + std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted."; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Converts each 2D point defined by the tuple of \a this array from the Polar to the + * Cartesian coordinate system. The two components of the tuple of \a this array are + * considered to contain (1) radius and (2) angle of the point in the Polar CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X and Y coordinates of the point in the Cartesian CS. The caller + * is to delete this array using decrRef() as it is no more needed. The array + * does not contain any textual info on components. + * \throw If \a this->getNumberOfComponents() != 2. + */ DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=2) throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !"); @@ -1952,8 +3233,20 @@ DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::E return ret; } +/*! + * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to + * the Cartesian coordinate system. The three components of the tuple of \a this array + * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in + * the Cylindrical CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X, Y and Z coordinates of the point in the Cartesian CS. The info + * on the third component is copied from \a this array. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 3. + */ DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=3) throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !"); @@ -1972,8 +3265,20 @@ DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exc return ret; } +/*! + * Converts each 3D point defined by the tuple of \a this array from the Spherical to + * the Cartesian coordinate system. The three components of the tuple of \a this array + * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the + * point in the Cylindrical CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X, Y and Z coordinates of the point in the Cartesian CS. The info + * on the third component is copied from \a this array. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 3. + */ DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=3) throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !"); @@ -1991,8 +3296,18 @@ DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::E return ret; } +/*! + * Computes the doubly contracted product of every tensor defined by the tuple of \a this + * array contating 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * is calculated from the tuple (t) of \a this array as follows: + * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. + * The caller is to delete this result array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6) throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !"); @@ -2006,6 +3321,16 @@ DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_K return ret; } +/*! + * Computes the determinant of every square matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * is the determinant of matrix of the corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2034,8 +3359,19 @@ DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Excep } } +/*! + * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3 + * components, whose each tuple contains the eigenvalues of the matrix of + * corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6) throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !"); @@ -2049,8 +3385,19 @@ DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Excep return ret; } +/*! + * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9 + * components, whose each tuple contains 3 eigenvectors of the matrix of + * corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6) throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !"); @@ -2069,8 +3416,20 @@ DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exce return ret; } +/*! + * Computes the inverse matrix of every matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of components as \a this one, whose each tuple is the inverse + * matrix of the matrix of corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4) throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !"); @@ -2116,8 +3475,20 @@ if(nbOfComp==6) return ret; } +/*! + * Computes the trace of every matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing + * 1 component, whose each tuple is the trace of + * the matrix of corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4) throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !"); @@ -2138,8 +3509,18 @@ DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception) return ret; } +/*! + * Computes the stress deviator tensor of every stress tensor defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of components and tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfComp=getNumberOfComponents(); if(nbOfComp!=6) throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !"); @@ -2161,6 +3542,15 @@ DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exceptio return ret; } +/*! + * Computes the magnitude of every vector defined by the tuple of + * \a this array. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and one component. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + */ DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2180,26 +3570,68 @@ DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Excepti return ret; } +/*! + * Computes the maximal value within every tuple of \a this array. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and one component. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \sa DataArrayDouble::maxPerTupleWithCompoId + */ DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception) { checkAllocated(); int nbOfComp=getNumberOfComponents(); - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); int nbOfTuple=getNumberOfTuples(); ret->alloc(nbOfTuple,1); const double *src=getConstPointer(); double *dest=ret->getPointer(); for(int i=0;igetNumberOfTuples() * \c this->getNumberOfTuples() tuples. - * \n This returned array contains the euclidian distance for each tuple in \a this. - * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0. - * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble) - * + * Computes the maximal value within every tuple of \a this array and it returns the first component + * id for each tuple that corresponds to the maximal value within the tuple. + * + * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the + * same number of tuples and only one component. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and one component. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \sa DataArrayDouble::maxPerTuple + */ +DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr ret0=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); + int nbOfTuple=getNumberOfTuples(); + ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret0->getPointer(); int *dest1=ret1->getPointer(); + for(int i=0;igetNumberOfTuples() * \c this->getNumberOfTuples() tuples. + * \n This returned array contains the euclidian distance for each tuple in \a this. + * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0. + * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble) + * * \warning use this method with care because it can leads to big amount of consumed memory ! * * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. @@ -2230,8 +3662,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const thro outData[j*nbOfTuples+i]=dist; } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -2281,10 +3712,15 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da outData[i*nbOfTuples+j]=dist; } } - ret->incrRef(); - return ret; + return ret.retn(); } +/*! + * Sorts value within every tuple of \a this array. + * \param [in] asc - if \a true, the values are sorted in ascending order, else, + * in descending order. + * \throw If \a this is not allocated. + */ void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2300,14 +3736,27 @@ void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Converts every value of \a this array to its absolute value. + * \throw If \a this is not allocated. + */ void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception) { checkAllocated(); double *ptr=getPointer(); - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(fabs)); + declareAsNew(); } +/*! + * Apply a liner function to a given component of \a this array, so that + * an array element (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If \a this is not allocated. + */ void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2319,27 +3768,39 @@ void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KER declareAsNew(); } +/*! + * Apply a liner function to all elements of \a this array, so that + * an element _x_ becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If \a this is not allocated. + */ void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception) { checkAllocated(); double *ptr=getPointer(); - int nbOfElems=getNbOfElems(); - for(int i=0;istd::numeric_limits::min()) { @@ -2356,8 +3817,12 @@ void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception) } /*! - * This method returns a newly allocated array containing the application of negate on \b this. - * This method throws an INTERP_KERNEL::Exception if \b this is not allocated. + * Returns a full copy of \a this array except that sign of all elements is reversed. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception) { @@ -2372,6 +3837,84 @@ DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception) return newArr; } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes val ^ x . Contrary to DataArrayInt::applyPow + * all values in \a this have to be >= 0 if val is \b not integer. + * \param [in] val - the value used to apply pow on all array elements. + * \throw If \a this is not allocated. + * \warning If an exception is thrown because of presence of 0 element in \a this + * array and \a val is \b not integer, all elements processed before detection of the zero element remain + * modified. + */ +void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + double *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + int val2=(int)val; + bool isInt=((double)val2)==val; + if(!isInt) + { + for(std::size_t i=0;i=0) + *ptr=pow(*ptr,val); + else + { + std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + for(std::size_t i=0;i= 0 !"); + double *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;igetNumberOfComponents()) contrary to the other DataArrayDouble::applyFunc overload method. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc1. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and \a nbOfComp components. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2440,6 +3993,19 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) cons return newArr; } +/*! + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc0. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and components as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If computing \a func fails. + */ DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2472,8 +4038,19 @@ DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP } /*! - * This method is equivalent than DataArrayDouble::applyFunc, except that here components names are used to determine vars orders. - * If 'func' contains vars that are not in \c this->getInfoOnComponent() an exception will be thrown. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc2. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If \a func contains vars that are not in \a this->getInfoOnComponent(). + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2516,8 +4093,20 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con } /*! - * This method is equivalent than DataArrayDouble::applyFunc, except that here order of vars is passed explicitely in parameter. - * In 'func' contains vars not in 'varsOrder' an exception will be thrown. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc3. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] varsOrder - sequence of vars defining their order. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If \a func contains vars not in \a varsOrder. + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2595,27 +4184,52 @@ void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exc declareAsNew(); } -DataArrayDoubleIterator *DataArrayDouble::iterator() +DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception) { return new DataArrayDoubleIterator(this); } +/*! + * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional + * array whose values are within a given range. Textual data is not copied. + * \param [in] vmin - a lowest acceptable value (included). + * \param [in] vmax - a greatest acceptable value (included). + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
+ * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". + */ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); const double *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;i=vmin && *cptr<=vmax) - res.push_back(i); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } +/*! + * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). + */ DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { std::vector tmp(2); @@ -2623,6 +4237,19 @@ DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const Dat return Aggregate(tmp); } +/*! + * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If getNumberOfComponents() of arrays within \a arr. + */ DataArrayDouble *DataArrayDouble::Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -2640,15 +4267,31 @@ DataArrayDouble *DataArrayDouble::Aggregate(const std::vectorgetNumberOfTuples(); } - DataArrayDouble *ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbt,nbOfComp); double *pt=ret->getPointer(); for(it=a.begin();it!=a.end();it++) pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); ret->copyStringInfoFrom(*(a[0])); - return ret; + return ret.retn(); } +/*! + * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If any given array is not allocated. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + */ DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { std::vector arr(2); @@ -2656,6 +4299,21 @@ DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArra return Meld(arr); } +/*! + * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If any given array is not allocated. + * \throw If getNumberOfTuples() of arrays within \a arr is different. + */ DataArrayDouble *DataArrayDouble::Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -2697,6 +4355,22 @@ DataArrayDouble *DataArrayDouble::Meld(const std::vectorgetNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2726,6 +4400,23 @@ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble containing a cross product of two given arrays, so that + * the i-th tuple of the result array contains 3 components of a vector which is a cross + * product of two vectors defined by the i-th tuples of given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples in the given arrays must be the same. + * Number of components in the given arrays must be 3. + * \param [in] a1 - a given array. + * \param [in] a2 - another given array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 3 + * \throw If \a a2->getNumberOfComponents() != 3 + */ DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2753,6 +4444,19 @@ DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const return ret; } +/*! + * Returns a new DataArrayDouble containing maximal values of two given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples and components in the given arrays must be the same. + * \param [in] a1 - an array to compare values with another one. + * \param [in] a2 - another array to compare values with the first one. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2775,6 +4479,19 @@ DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble containing minimal values of two given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples and components in the given arrays must be the same. + * \param [in] a1 - an array to compare values with another one. + * \param [in] a2 - another array to compare values with the first one. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2797,6 +4514,31 @@ DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2, + * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to sum up. + * \param [in] a2 - another array to sum up. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2864,15 +4606,33 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - ret->incrRef(); - return ret; + return ret.retn(); } +/*! + * Adds values of another DataArrayDouble to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is added to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] += _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] += _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] += _a2_ [ 0, j ]. + * + * \param [in] other - an array to add to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual !"; + checkAllocated(); + other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -2910,6 +4670,31 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a subtraction of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to subtract from. + * \param [in] a2 - an array to subtract. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2926,8 +4711,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -2939,8 +4723,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -2958,8 +4741,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -2968,11 +4750,30 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat } } +/*! + * Subtract values of another DataArrayDouble from values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is subtracted from the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] -= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] -= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] -= _a2_ [ 0, j ]. + * + * \param [in] other - an array to subtract from \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual !"; + checkAllocated(); + other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -3010,6 +4811,31 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_ declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a product of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a product of the corresponding values of \a a1 and + * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a factor array. + * \param [in] a2 - another factor array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3077,15 +4903,33 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - ret->incrRef(); - return ret; + return ret.retn(); } +/*! + * Multiply values of another DataArrayDouble to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is multiplied to the corresponding value of \a this array, i.e. + * _this_ [ i, j ] *= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _this_ [ i, j ] *= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _this_ [ i, j ] *= _a2_ [ 0, j ]. + * + * \param [in] other - an array to multiply to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !"; + checkAllocated(); + other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -3123,6 +4967,32 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_K declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a division of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \warning No check of division by zero is performed! + * \param [in] a1 - a numerator array. + * \param [in] a2 - a denominator array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3139,8 +5009,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -3152,8 +5021,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -3171,8 +5039,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -3181,11 +5048,31 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr } } +/*! + * Divide values of \a this array by values of another DataArrayDouble. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] /= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] /= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] /= _a2_ [ 0, j ]. + * + * \warning No check of division by zero is performed! + * \param [in] other - an array to divide \a this one by. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !"; + checkAllocated(); + other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -3223,6 +5110,86 @@ void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KER declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3 + * valid cases. + * + * \param [in] a1 - an array to pow up. + * \param [in] a2 - another array to sum up. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. + * \throw If there is a negative value in \a a1. + */ +DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); + const double *ptr1(a1->begin()),*ptr2(a2->begin()); + double *ptr=ret->getPointer(); + for(int i=0;i=0) + { + *ptr=pow(*ptr1,*ptr2); + } + else + { + std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Apply pow on values of another DataArrayDouble to values of \a this one. + * + * \param [in] other - an array to pow to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() + * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1 + * \throw If there is a negative value in \a this. + */ +void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !"); + int nbOfTuple=getNumberOfTuples(); + int nbOfTuple2=other->getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !"); + double *ptr=getPointer(); + const double *ptrc=other->begin(); + for(int i=0;i=0) + *ptr=pow(*ptr,*ptrc); + else + { + std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + /*! * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. * Server side. @@ -3313,7 +5280,7 @@ DataArrayDoubleIterator::~DataArrayDoubleIterator() _da->decrRef(); } -DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() +DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception) { if(_tuple_id<_nb_tuple) { @@ -3331,7 +5298,7 @@ DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb } -std::string DataArrayDoubleTuple::repr() const +std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception) { std::ostringstream oss; oss.precision(17); oss << "("; for(int i=0;i<_nb_of_compo-1;i++) @@ -3369,47 +5336,47 @@ DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCom } } +/*! + * Returns a new instance of DataArrayInt. The caller is to delete this array + * using decrRef() as it is no more needed. + */ DataArrayInt *DataArrayInt::New() { return new DataArrayInt; } -bool DataArrayInt::isAllocated() const +/*! + * Checks if raw data is allocated. Read more on the raw data + * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return bool - \a true if the raw data is allocated, \a false else. + */ +bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception) { return getConstPointer()!=0; } +/*! + * Checks if raw data is allocated and throws an exception if it is not the case. + * \throw If the raw data is not allocated. + */ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception) { if(!isAllocated()) throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } -/*! - * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' - * and if 'this' is not allocated it will change the number of components of 'this'. - * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method. - * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown. - */ -void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception) +std::size_t DataArrayInt::getHeapMemorySize() const { - if(getNumberOfComponents()!=(int)info.size()) - { - if(!isAllocated()) - _info_on_compo=info; - else - { - std::ostringstream oss; oss << "DataArrayInt::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - _info_on_compo=info; + std::size_t sz=_mem.getNbOfElemAllocated(); + sz*=sizeof(int); + return DataArray::getHeapMemorySize()+sz; } /*! - * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. - * If one or more conditions is not fulfilled an exception will be thrown. + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. */ int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception) { @@ -3427,26 +5394,30 @@ int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception) } /*! - * This method expects that \b this is well allocated. If not an INTERP_KERNEL::Exception will be thrown. This method is useful for a quick comparison of many instances of DataArrayInt. + * Returns an integer value characterizing \a this array, which is useful for a quick + * comparison of many instances of DataArrayInt. + * \return int - the hash value. + * \throw If \a this is not allocated. */ int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception) { checkAllocated(); - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); int ret=nbOfElems*65536; int delta=3; if(nbOfElems>48) delta=nbOfElems/8; int ret0=0; const int *pt=begin(); - for(int i=0;igetNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -3531,14 +5645,19 @@ void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception) declareAsNew(); } -std::string DataArrayInt::repr() const +/*! + * Returns a textual and human readable representation of \a this instance of + * DataArrayInt. This text is shown when a DataArrayInt is printed in Python. + * \return std::string - text describing \a this DataArrayInt. + */ +std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception) { std::ostringstream ret; reprStream(ret); return ret.str(); } -std::string DataArrayInt::reprZip() const +std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception) { std::ostringstream ret; reprZipStream(ret); @@ -3547,6 +5666,7 @@ std::string DataArrayInt::reprZip() const void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); std::string idt(indent,' '); ofs << idt << "\n" << idt; @@ -3554,31 +5674,31 @@ void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, con ofs << std::endl << idt << "\n"; } -void DataArrayInt::reprStream(std::ostream& stream) const +void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { stream << "Name of int array : \"" << _name << "\"\n"; reprWithoutNameStream(stream); } -void DataArrayInt::reprZipStream(std::ostream& stream) const +void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { stream << "Name of int array : \"" << _name << "\"\n"; reprZipWithoutNameStream(stream); } -void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const +void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { DataArray::reprWithoutNameStream(stream); _mem.repr(getNumberOfComponents(),stream); } -void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const +void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) { DataArray::reprWithoutNameStream(stream); _mem.reprZip(getNumberOfComponents(),stream); } -void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const +void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception) { int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); const int *data=getConstPointer(); @@ -3596,14 +5716,77 @@ void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) cons } /*! - * This method expects a number of components equal to 1. - * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v is replaced by - * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd'). - * This method is safe that is to say if there is a value in 'this' not in [0,std::distance('indArrBg','indArrEnd')) an exception - * will be thrown. + * Method that gives a quick overvien of \a this for python. + */ +void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; + stream << "DataArrayInt C++ instance at " << this << ". "; + if(isAllocated()) + { + int nbOfCompo=(int)_info_on_compo.size(); + if(nbOfCompo>=1) + { + int nbOfTuples=getNumberOfTuples(); + stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; + reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); + } + else + stream << "Number of components : 0."; + } + else + stream << "*** No data allocated ****"; +} + +void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception) +{ + const int *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbOfCompo=(int)_info_on_compo.size(); + std::ostringstream oss2; oss2 << "["; + std::string oss2Str(oss2.str()); + bool isFinished=true; + for(int i=0;i1) + { + oss2 << "("; + for(int j=0;jgetNumberOfComponents() != 1 + * \throw If any value of \a this can't be used as a valid index for + * [\a indArrBg, \a indArrEnd). */ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !"); int nbElemsIn=(int)std::distance(indArrBg,indArrEnd); @@ -3623,25 +5806,55 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd } /*! - * 'this' should be allocated and with numberOfComponents set to one. If not an exception will be thrown. - * This method takes as input an array defined by ['arrBg','arrEnd'). The size of the array (std::distance(arrBg,arrEnd)) is equal to the number of cast + 1. - * The values contained in ['arrBg','arrEnd') should be sorted ascendently. No check of this will be done. If not the result is not waranted. - * For each cast j the value range that defines the cast is equal to [arrBg[j],arrBg[j+1]). - * This method returns three arrays (to be managed by the caller). - * This method is typically usefull for entity number spliting by types for example. - * Example : If 'this' contains [6,5,0,3,2,7,8,1,4] and if ['arrBg','arrEnd') contains [0,4,9] then the output of this method will be : - * - 'castArr' : [1,1,0,0,0,1,1,0,1] - * - 'rankInsideCast' : [2,1,0,3,2,3,4,1,0] - * - 'return' : [0,1] + * Computes distribution of values of \a this one-dimensional array between given value + * ranges (casts). This method is typically useful for entity number spliting by types, + * for example. + * \warning The values contained in \a arrBg should be sorted ascendently. No + * check of this is be done. If not, the result is not warranted. + * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th + * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range, + * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a + * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg + * should be more than every value in \a this array. + * \param [in] arrEnd - specifies the end of the array \a arrBg, so that + * the last value of \a arrBg is \a arrEnd[ -1 ]. + * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array + * (same number of tuples and components), the caller is to delete + * using decrRef() as it is no more needed. + * This array contains indices of ranges for every value of \a this array. I.e. + * the i-th value of \a castArr gives the index of range the i-th value of \a this + * belongs to. Or, in other words, this parameter contains for each tuple in \a + * this in which cast it holds. + * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this + * array, the caller is to delete using decrRef() as it is no more needed. + * This array contains ranks of values of \a this array within ranges + * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of + * the i-th value of \a this array within the \a castArr[ i ]-th range, to which + * the i-th value of \a this belongs to. Or, in other words, this param contains + * for each tuple its rank inside its cast. The rank is computed as difference + * between the value and the lowest value of range. + * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of + * ranges (casts) to which at least one value of \a this array belongs. + * Or, in other words, this param contains the casts that \a this contains. + * The caller is to delete this array using decrRef() as it is no more needed. + * + * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then + * the output of this method will be : + * - \a castArr : [1,1,0,0,0,1,1,0,1] + * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0] + * - \a castsPresent : [0,1] * - * @param castArr is a returned param has the same number of tuples than 'this' and number of components set to one. In case of sucess, this param contains for each tuple in 'this' in which cast it holds. - * @param rankInsideCast is an another returned param has the same number of tuples than 'this' and number of components set to one too. In case of sucess, this param contains for each tuple its rank inside its cast. - * @param castsPresent the casts that 'this' contains. - * @throw if a value in 'this' is greater or equal to the last value of ['arrBg','arrEnd') + * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the + * range #1 and its rank within this range is 2; etc. + * + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a arrEnd - arrBg < 2. + * \throw If any value of \a this is not less than \a arrEnd[-1]. */ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !"); int nbOfTuples=getNumberOfTuples(); @@ -3651,7 +5864,7 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, nbOfCast--; const int *work=getConstPointer(); typedef std::reverse_iterator rintstart; - rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater of equal 2 + rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2 rintstart end2(arrBg); MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); @@ -3680,24 +5893,30 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, } ret3->alloc((int)castsDetected.size(),1); std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer()); - ret1->incrRef(); - castArr=ret1; - ret2->incrRef(); - rankInsideCast=ret2; - ret3->incrRef(); - castsPresent=ret3; + castArr=ret1.retn(); + rankInsideCast=ret2.retn(); + castsPresent=ret3.retn(); } /*! - * This method expects a number of components equal to 1. - * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v on place i, place indArr[v] will have - * value i. - * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd'). - * This method is half/safe that is to say if there is location i so that indArr[v] is not in [0,this->getNumberOfTuples()) an exception - * will be thrown. + * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from + * values of \a this (\a a) and the given (\a indArr) arrays as follows: + * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ], + * new value in place \a indArr[ \a v ] is i. + * \param [in] indArrBg - the array holding indices within the result array to assign + * indices of values of \a this array pointing to values of \a indArrBg. + * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that + * the last value of \a indArrBg is \a indArrEnd[ -1 ]. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any value of \a this array is not a valid index for \a indArrBg array. + * \throw If any value of \a indArrBg is not a valid index for \a this array. */ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !"); int nbElemsIn=(int)std::distance(indArrBg,indArrEnd); @@ -3709,25 +5928,42 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int int *tmp=ret->getPointer(); for(int i=0;i=0 && pos=0 && *pt=0 && posincrRef(); - return ret; + return ret.retn(); } /*! - * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering. + * Creates a one-dimensional DataArrayInt of given length, whose contents are computed + * from values of \a this array, which is supposed to contain a renumbering map in + * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode. + * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering. + * \param [in] newNbOfElem - the number of tuples in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * + * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".
+ * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(newNbOfElem,1); int nbOfOldNodes=getNumberOfTuples(); const int *old2New=getConstPointer(); @@ -3735,15 +5971,44 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const for(int i=0;i!=nbOfOldNodes;i++) if(old2New[i]!=-1) pt[old2New[i]]=i; - return ret; + return ret.retn(); } /*! - * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering. + * This method is similar to DataArrayInt::invertArrayO2N2N2O except that + * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8] + */ +DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(newNbOfElem,1); + int nbOfOldNodes=getNumberOfTuples(); + const int *old2New=getConstPointer(); + int *pt=ret->getPointer(); + for(int i=nbOfOldNodes-1;i>=0;i--) + if(old2New[i]!=-1) + pt[old2New[i]]=i; + return ret.retn(); +} + +/*! + * Creates a one-dimensional DataArrayInt of given length, whose contents are computed + * from values of \a this array, which is supposed to contain a renumbering map in + * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode. + * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering. + * \param [in] newNbOfElem - the number of tuples in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * + * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". + * + * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". */ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { - DataArrayInt *ret=DataArrayInt::New(); + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(oldNbOfElem,1); const int *new2Old=getConstPointer(); int *pt=ret->getPointer(); @@ -3751,28 +6016,55 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const int nbOfNewElems=getNumberOfTuples(); for(int i=0;i a=deepCpy(); @@ -3782,34 +6074,169 @@ bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& othe return a->isEqualWithoutConsideringStr(*b); } -void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception) +/*! + * Sorts values of the array. + * \param [in] asc - \a true means ascending order, \a false, descending. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ +void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); + _mem.sort(asc); + declareAsNew(); +} + +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ +void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); +} + +/*! + * Checks that \a this array is consistently **increasing** or **decreasing** in value. + * If not an exception is thrown. + * \param [in] increasing - if \a true, the array values should be increasing. + * \throw If sequence of values is not strictly monotonic in agreement with \a + * increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + */ +void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) +{ + if(!isMonotonic(increasing)) + { + if (increasing) + throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !"); + else + throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !"); + } +} + +/*! + * Checks that \a this array is consistently **increasing** or **decreasing** in value. + * \param [in] increasing - if \a true, array values should be increasing. + * \return bool - \a true if values change in accordance with \a increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + */ +bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !"); + int nbOfElements=getNumberOfTuples(); + const int *ptr=getConstPointer(); + if(nbOfElements==0) + return true; + int ref=ptr[0]; + if(increasing) + { + for(int i=1;i=ref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;iref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;igetIJ(ret->getIJ(i),0) - * If such permutation is not possible because it exists some elements in 'other' not in 'this', an exception will be thrown. + * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given + * one-dimensional arrays that must be of the same length. The result array describes + * correspondence between \a this and \a other arrays, so that + * other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0). If such a permutation is + * not possible because some element in \a other is not in \a this, an exception is thrown. + * \param [in] other - an array to compute permutation to. + * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array + * from \a this to \a other. The caller is to delete this array using decrRef() as it is + * no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). + * \throw If \a other includes a value which is not in \a this array. + * + * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". + * + * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". */ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !"); int nbTuple=getNumberOfTuples(); + other.checkAllocated(); if(nbTuple!=other.getNumberOfTuples()) throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); @@ -3831,48 +6258,89 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const } retToFill[i]=(*it).second; } - ret->incrRef(); - return ret; + return ret.retn(); } -void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) +/*! + * Sets a C array to be used as raw data of \a this. The previously set info + * of components is retained and re-sized. + * For more info see \ref MEDCouplingArraySteps1. + * \param [in] array - the C array to be used as raw data of \a this. + * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. + * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, + * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, + * \c free(\c array ) will be called. + * \param [in] nbOfTuple - new number of tuples in \a this. + * \param [in] nbOfCompo - new number of components in \a this. + */ +void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); declareAsNew(); } -void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) +void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { - _nb_of_tuples=nbOfTuple; _info_on_compo.resize(nbOfCompo); _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); declareAsNew(); } +/*! + * Returns a new DataArrayInt holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. + * \warning Do not confuse this method with transpose()! + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(_mem.isNull()) throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !"); int *tab=_mem.fromNoInterlace(getNumberOfComponents()); DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); return ret; } +/*! + * Returns a new DataArrayInt holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. + * \warning Do not confuse this method with transpose()! + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(_mem.isNull()) throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !"); int *tab=_mem.toNoInterlace(getNumberOfComponents()); DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); return ret; } -void DataArrayInt::renumberInPlace(const int *old2New) +/*! + * Permutes values of \a this array as required by \a old2New array. The values are + * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains + * the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + */ +void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); int *tmp=new int[nbTuples*nbOfCompo]; @@ -3884,8 +6352,19 @@ void DataArrayInt::renumberInPlace(const int *old2New) declareAsNew(); } -void DataArrayInt::renumberInPlaceR(const int *new2Old) +/*! + * Permutes values of \a this array as required by \a new2Old array. The values are + * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains + * the same as in \this one. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + */ +void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); int *tmp=new int[nbTuples*nbOfCompo]; @@ -3898,15 +6377,23 @@ void DataArrayInt::renumberInPlaceR(const int *new2Old) } /*! - * This method expects that 'this' is allocated, if not an exception is thrown. - * This method in case of success returns a newly created array the user should deal with. - * In the case of having a renumber array in "old to new" format. More info on renumbering \ref MEDCouplingArrayRenumbering "here". + * Returns a copy of \a this array with values permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. + * Number of tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ -DataArrayInt *DataArrayInt::renumber(const int *old2New) const +DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,nbOfCompo); ret->copyStringInfoFrom(*this); const int *iptr=getConstPointer(); @@ -3914,14 +6401,26 @@ DataArrayInt *DataArrayInt::renumber(const int *old2New) const for(int i=0;icopyStringInfoFrom(*this); - return ret; + return ret.retn(); } -DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const +/*! + * Returns a copy of \a this array with values permuted as required by \a new2Old array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of + * tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + */ +DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,nbOfCompo); ret->copyStringInfoFrom(*this); const int *iptr=getConstPointer(); @@ -3929,20 +6428,28 @@ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const for(int i=0;icopyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * Idem DataArrayInt::renumber method except that the number of tuples is reduced. - * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). - * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is - * omitted. + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all + * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which + * \a old2New[ i ] is negative, is missing from the result array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old tuple and giving negative position for + * for i-th old tuple that should be omitted. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. */ -DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const +DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbTuples=getNumberOfTuples(); int nbOfCompo=getNumberOfComponents(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(newNbOfTuple,nbOfCompo); const int *iptr=getConstPointer(); int *optr=ret->getPointer(); @@ -3953,16 +6460,29 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); } ret->copyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. - * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new. + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { - DataArrayInt *ret=DataArrayInt::New(); + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); int nbComp=getNumberOfComponents(); ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); ret->copyStringInfoFrom(*this); @@ -3972,14 +6492,31 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); ret->copyStringInfoFrom(*this); - return ret; + return ret.retn(); } /*! - * This method is equivalent to DataArrayInt::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * This method is equivalent to selectByTupleId() except that it prevents coping data + * from behind the end of \a this array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). */ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); int nbComp=getNumberOfComponents(); int oldNbOfTuples=getNumberOfTuples(); @@ -3994,49 +6531,62 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int else throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely. - * The convention is as python one. ['bg','end2') with steps of 'step'. - * Returns a newly created array. - * This method is an extension of DataArrayInt::substr method. - * - * \sa DataArrayInt::substr + * Returns a shorten copy of \a this array. The new DataArrayInt contains every + * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th + * tuple. Indices of the selected tuples are the same as ones returned by the Python + * command \c range( \a bg, \a end2, \a step ). + * This method is equivalent to selectByTupleIdSafe() except that the input array is + * not constructed explicitly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] bg - index of the first tuple to copy from \a this array. + * \param [in] end2 - index of the tuple before which the tuples to copy are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \sa DataArrayInt::substr. */ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); ret->alloc(newNbOfTuples,nbComp); int *pt=ret->getPointer(); const int *srcPt=getConstPointer()+bg*nbComp; for(int i=0;icopyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'. - * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception - * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too. + * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges + * of tuples specified by \a ranges parameter. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] ranges - std::vector of std::pair's each of which defines a range + * of tuples in [\c begin,\c end) format. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a end < \a begin. + * \throw If \a end > \a this->getNumberOfTuples(). + * \throw If \a this is not allocated. */ -DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) +DataArray *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) { checkAllocated(); int nbOfComp=getNumberOfComponents(); int nbOfTuplesThis=getNumberOfTuples(); if(ranges.empty()) { - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,nbOfComp); ret->copyStringInfoFrom(*this); - return ret; + return ret.retn(); } int ref=ranges.front().first; int nbOfTuples=0; @@ -4075,16 +6625,22 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vectorgetPointer(); for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * This method works only for arrays having single component. - * If this contains the array a1 containing [9,10,0,6,4,11,3,7] this method returns an array a2 [5,6,0,3,2,7,1,4]. - * By doing a1.renumber(a2) the user will obtain array a3 equal to a1 sorted. - * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldDouble::renumberCells when check is set to true. - * This method throws an exception if more 2 or more elements in 'this' are same. + * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode. + * This map, if applied to \a this array, would make it sorted. For example, if + * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array + * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call + * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11]. + * This method is useful for renumbering (in MED file for example). For more info + * on renumbering see \ref MEDCouplingArrayRenumbering. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If there are equal values in \a this array. */ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception) { @@ -4095,20 +6651,44 @@ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERN const int *pt=getConstPointer(); int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples); DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(pt2,true,CPP_DEALLOC,nbTuples,1); + ret->useArray(pt2,true,C_DEALLOC,nbTuples,1); return ret; } /*! - * This method makes the assumption that 'this' is correctly set, and has exactly one component. If not an exception will be thrown. - * Given a sujective application defined by 'this' from a set of size this->getNumberOfTuples() to a set of size targetNb. - * 'targetNb'getNumberOfTuples(). 'this' should be surjective that is to say for each id in [0,'targetNb') it exists at least one tupleId tid - * so that this->getIJ(tid,0)==id. - * If not an exception will be thrown. - * This method returns 2 newly allocated arrays 'arr' and 'arrI', corresponding respectively to array and its corresponding index. - * This method is usefull for methods that returns old2New numbering concecutive to a reduction ( MEDCouplingUMesh::zipConnectivityTraducer, MEDCouplingUMesh::zipConnectivityTraducer for example) - * Example : if 'this' equals [0,3,2,3,2,2,1,2] this method will return arrI=[0,1,2,6,8] arr=[0, 6, 2,4,5,7, 1,3] - * That is to say elt id 2 has arrI[2+1]-arrI[2]=4 places in 'this'. The corresponding tuple ids are [2,4,5,7]. + * Returns two arrays describing a surjective mapping from \a this set of values (\a A) + * onto a set of values of size \a targetNb (\a B). The surjective function is + * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a + * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so + * that this->getIJ( tid, 0 ) == id.
+ * The first of out arrays returns indices of elements of \a this array, grouped by their + * place in the set \a B. The second out array is the index of the first one; it shows how + * many elements of \a A are mapped into each element of \a B.
+ * For more info on + * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example: + * - \a this: [0,3,2,3,2,2,1,2] + * - \a targetNb: 4 + * - \a arr: [0, 6, 2,4,5,7, 1,3] + * - \a arrI: [0,1,2,6,8] + * + * This result means:
+ * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and + * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);
+ * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and + * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : + * \a arrI[ 2+1 ]]);
etc. + * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more + * than the maximal value of \a A. + * \param [out] arr - a new instance of DataArrayInt returning indices of + * elements of \a this, grouped by their place in the set \a B. The caller is to delete + * this array using decrRef() as it is no more needed. + * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal + * elements of \a this. The caller is to delete this array using decrRef() as it + * is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any value in \a this is more or equal to \a targetNb. */ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception) { @@ -4124,11 +6704,11 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data for(int i=0;i=0 && tmp2getPointer(); for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++) retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr); - ret->incrRef(); - retI->incrRef(); - arr=ret; - arrI=retI; + arr=ret.retn(); + arrI=retI.retn(); } + /*! - * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example) - * The retrieved array minimizes the permutation. - * Let's take an example : - * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7. + * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed + * from a zip representation of a surjective format (returned e.g. by + * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()" + * for example). The result array minimizes the permutation.
+ * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example:
+ * - \a nbOfOldTuples: 10 + * - \a arr : [0,3, 5,7,9] + * - \a arrIBg : [0,2,5] + * - \a newNbOfTuples: 7 + * - result array : [0,1,2,0,3,4,5,4,6,4] * - * @param nbOfOldTuples is the number of tuples in initial array. - * @param arr is the list of tuples ids grouped by 'arrI' array - * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. - * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application + * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr. + * \param [in] arr - the array of tuple indices grouped by \a arrIBg array. + * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of + * (indices of) equal values. Its every element (except the last one) points to + * the first element of a group of equal values. + * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a + * arrIBg is \a arrIEnd[ -1 ]. + * \param [out] newNbOfTuples - number of tuples after surjection application. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ). */ -DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) +DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) { - if(!arr || !arrI) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !"); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfOldTuples,1); int *pt=ret->getPointer(); std::fill(pt,pt+nbOfOldTuples,-1); - int nbOfGrps=arrI->getNumberOfTuples()-1; - const int *cIPtr=arrI->getConstPointer(); - const int *cPtr=arr->getConstPointer(); + int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; + const int *cIPtr=arrIBg; for(int i=0;i=0 && arr[j]getNumberOfTuples()' tuples and 1 component. - * This methods returns an 'old2New' corresponding array that allows to follow the following rules : - * - Lower a value in tuple in 'this' is, higher is its priority. - * - If two tuples i and j have same value if igetNumberOfTuples()-1' - * - * Example if 'this' contains the following array : [2,0,1,1,0,1,2,0,1,1,0,0] this method returns [10,0,5,6,1,7,11,2,8,9,3,4] + * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode, + * which if applied to \a this array would make it sorted ascendingly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example:
+ * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0] + * - result: [10,0,5,6,1,7,11,2,8,9,3,4] + * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] + * + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception) { @@ -4240,14 +6842,16 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Ex for(int i=0;iincrRef(); - return ret; + return ret.retn(); } /*! - * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to - * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances - * that represents a renumbering array to check the real need in renumbering. + * Checks if contents of \a this array are equal to that of an array filled with + * iota(). This method is particularly useful for DataArrayInt instances that represent + * a renumbering array to check the real need in renumbering. + * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception) { @@ -4262,6 +6866,13 @@ bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception) return true; } +/*! + * Checks if all values in \a this array are equal to \a val. + * \param [in] val - value to check equality of array values to. + * \return bool - \a true if all values are \a val. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1 + */ bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4276,12 +6887,17 @@ bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception) return true; } +/*! + * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this + * array to the new one. + * \return DataArrayDouble * - the new instance of DataArrayInt. + */ DataArrayDouble *DataArrayInt::convertToDblArr() const { checkAllocated(); DataArrayDouble *ret=DataArrayDouble::New(); ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - int nbOfVals=getNbOfElems(); + std::size_t nbOfVals=getNbOfElems(); const int *src=getConstPointer(); double *dest=ret->getPointer(); std::copy(src,src+nbOfVals,dest); @@ -4290,15 +6906,23 @@ DataArrayDouble *DataArrayInt::convertToDblArr() const } /*! - * 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. - * This method check that interval is valid regarding this, if not an exception will be thrown. - * This method is a specialization of method DataArrayInt::selectByTupleId2. - * - * \sa DataArrayInt::selectByTupleId2 + * Returns a shorten copy of \a this array. The new DataArrayInt contains all + * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before + * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). + * This method is a specialization of selectByTupleId2(). + * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. + * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. + * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a tupleIdBg < 0. + * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). + \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). + * \sa DataArrayInt::selectByTupleId2 */ DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbt=getNumberOfTuples(); if(tupleIdBg<0) throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); @@ -4313,36 +6937,48 @@ DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(IN else trueEnd=nbt; int nbComp=getNumberOfComponents(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(trueEnd-tupleIdBg,nbComp); ret->copyStringInfoFrom(*this); std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret; + return ret.retn(); } /*! - * Contrary to DataArrayInt::changeNbOfComponents method this method is \b not const. The content - * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller. - * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown. - * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw ! - * This method erases all components info set before call ! + * Changes the number of components within \a this array so that its raw data **does + * not** change, instead splitting this data into tuples changes. + * \warning This method erases all (name and unit) component info set before! + * \param [in] newNbOfComp - number of components for \a this array to have. + * \throw If \a this is not allocated + * \throw If getNbOfElems() % \a newNbOfCompo != 0. + * \throw If \a newNbOfCompo is lower than 1. + * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). + * \warning This method erases all (name and unit) component info set before! */ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) { checkAllocated(); - int nbOfElems=getNbOfElems(); + if(newNbOfCompo<1) + throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !"); + std::size_t nbOfElems=getNbOfElems(); if(nbOfElems%newNbOfCompo!=0) throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !"); - _nb_of_tuples=nbOfElems/newNbOfCompo; + if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) + throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); _info_on_compo.clear(); _info_on_compo.resize(newNbOfCompo); declareAsNew(); } /*! - * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised. - * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of - * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method. + * Changes the number of components within \a this array to be equal to its number + * of tuples, and inversely its number of tuples to become equal to its number of + * components. So that its raw data **does not** change, instead splitting this + * data into tuples changes. + * \warning This method erases all (name and unit) component info set before! + * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! + * \throw If \a this is not allocated. + * \sa rearrange() */ void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception) { @@ -4352,14 +6988,22 @@ void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception) } /*! - * This method builds a new instance of DataArrayInt (to deal with) that is reduction or an extension of 'this'. - * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. - * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then the result array is shorten as each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is + * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp + * components. + * \param [in] newNbOfComp - number of components for the new array to have. + * \param [in] dftValue - value assigned to new values added to the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception) { checkAllocated(); - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(getNumberOfTuples(),newNbOfComp); const int *oldc=getConstPointer(); int *nc=ret->getPointer(); @@ -4378,18 +7022,39 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); ret->setName(getName().c_str()); - return ret; + return ret.retn(); } +/*! + * Changes number of tuples in the array. If the new number of tuples is smaller + * than the current number the array is truncated, otherwise the array is extended. + * \param [in] nbOfTuples - new number of tuples. + * \throw If \a this is not allocated. + */ void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { checkAllocated(); - _mem.reAlloc((int)_info_on_compo.size()*nbOfTuples); - _nb_of_tuples=nbOfTuples; + _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); declareAsNew(); } -DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) + +/*! + * Returns a copy of \a this array composed of selected components. + * The new DataArrayInt has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result array + * can be either less, same or more than \a this->getNbOfElems(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new array. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + * + * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + */ +DataArray *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) { checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); @@ -4405,15 +7070,20 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compo for(int i=0;iincrRef(); - return ret; + return ret.retn(); } /*! - * This method melds the components of 'this' with components of 'other'. - * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' - * before the call and the number of components of 'other'. - * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + * Appends components of another array to components of \a this one, tuple by tuple. + * So that the number of tuples of \a this array remains the same and the number of + * components increases. + * \param [in] other - the DataArrayInt to append to \a this one. + * \throw If \a this is not allocated. + * \throw If \a this and \a other arrays have different number of tuples. + * + * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". + * + * \ref py_mcdataarrayint_meldwith "Here is a Python example". */ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { @@ -4426,7 +7096,7 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); int nbOfComp1=getNumberOfComponents(); int nbOfComp2=other->getNumberOfComponents(); - int *newArr=new int[nbOfTuples*(nbOfComp1+nbOfComp2)]; + int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int)); int *w=newArr; const int *inp1=getConstPointer(); const int *inp2=other->getConstPointer(); @@ -4435,19 +7105,37 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce w=std::copy(inp1,inp1+nbOfComp1,w); w=std::copy(inp2,inp2+nbOfComp2,w); } - useArray(newArr,true,CPP_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); + useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); std::vector compIds(nbOfComp2); for(int i=0;igetNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + * + * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". + */ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !"); + checkAllocated(); + a->checkAllocated(); copyPartOfStringInfoFrom2(compoIds,*a); std::size_t partOfCompoSz=compoIds.size(); int nbOfCompo=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); + int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); const int *ac=a->getConstPointer(); int *nc=getPointer(); for(int i=0;igetNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". */ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -4472,18 +7190,55 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end int nbOfTuples=getNumberOfTuples(); DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg); - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } int *pt=getPointer()+bgTuples*nbComp+bgComp; const int *srcPt=a->getConstPointer(); - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign values of \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - this parameter is checked only if the + * *mode of usage* is the first; if it is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() != (endComp - bgComp) . + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() != (endComp - bgComp). + * + * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". */ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -4519,7 +7309,7 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, int newNbOfTuples=(int)std::distance(bgTuples,endTuples); int newNbOfComp=(int)std::distance(bgComp,endComp); bool assignTech=true; - if(a->getNbOfElems()==newNbOfTuples*newNbOfComp) + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) { if(strictCompoCompare) a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); @@ -4538,7 +7328,7 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); for(const int *z=bgComp;z!=endComp;z++,srcPt++) { - pt[(*w)*nbComp+(*z)]=*srcPt; + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; } } } @@ -4550,14 +7340,31 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); for(const int *z=bgComp;z!=endComp;z++,srcPt2++) { - pt[(*w)*nbComp+(*z)]=*srcPt2; + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; } } } } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples and components to assign to are defined by C arrays of indices. + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (\a pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * + * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". */ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception) { @@ -4571,13 +7378,53 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int for(const int *z=bgComp;z!=endComp;z++) { DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(*w)*nbComp+(*z)]=a; + pt[(std::size_t)(*w)*nbComp+(*z)]=a; } } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayInt (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - this parameter is checked only in the first + * *mode of usage*; if \a strictCompoCompare is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". */ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -4592,7 +7439,7 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); int newNbOfTuples=(int)std::distance(bgTuples,endTuples); bool assignTech=true; - if(a->getNbOfElems()==newNbOfTuples*newNbOfComp) + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) { if(strictCompoCompare) a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); @@ -4610,7 +7457,7 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, for(int j=0;j(pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". */ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -4643,18 +7511,94 @@ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int for(int j=0;jcheckAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + int newNbOfComp=(int)std::distance(bgComp,endComp); + int nbComp=getNumberOfComponents(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + const int *srcPt=a->getConstPointer(); + int *pt=getPointer()+bgTuples*nbComp; + if(assignTech) + { + for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 2. + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * the corresponding (\a this or \a a) array. */ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { - if(!a) + if(!a || !tuplesSelec) throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !"); checkAllocated(); a->checkAllocated(); @@ -4691,13 +7635,35 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayInt::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by \a tuplesSelec->getNumberOfTuples(). + * The tuples to copy are defined by values of a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a a array. */ -void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) +void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { + if(!aBase || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayInt *a=dynamic_cast(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !"); checkAllocated(); a->checkAllocated(); tuplesSelec->checkAllocated(); @@ -4729,13 +7695,37 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr } /*! - * 'this' and 'a' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayInt::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to copy are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by number of tuples to copy. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a a. + * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). + * \throw If parameters specifying tuples to copy, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for the array \a a. */ -void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) +void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayInt *a=dynamic_cast(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !"); checkAllocated(); a->checkAllocated(); int nbOfComp=getNumberOfComponents(); @@ -4758,9 +7748,16 @@ void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataAr } /*! - * This method is equivalent to DataArrayInt::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()). - * If one of these check fails an INTERP_KERNEL::Exception will be thrown. - * So this method is safe but expensive if used to go through all data of \b this. + * Returns a value located at specified tuple and component. + * This method is equivalent to DataArrayInt::getIJ() except that validity of + * parameters is checked. So this method is safe but expensive if used to go through + * all values of \a this. + * \param [in] tupleId - index of tuple of interest. + * \param [in] compoId - index of component of interest. + * \return double - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. + * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. */ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { @@ -4775,13 +7772,15 @@ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL: std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - return _mem[tupleId*((int)_info_on_compo.size())+compoId]; + return _mem[tupleId*_info_on_compo.size()+compoId]; } /*! - * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. - * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. - * And to finish this method works for arrays that have number of tuples >= 1. + * Returns the last value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. */ int DataArrayInt::back() const throw(INTERP_KERNEL::Exception) { @@ -4794,6 +7793,12 @@ int DataArrayInt::back() const throw(INTERP_KERNEL::Exception) return *(getConstPointer()+nbOfTuples-1); } +/*! + * Assign pointer to one array to a pointer to another appay. Reference counter of + * \a arrayToSet is incremented / decremented. + * \param [in] newArray - the pointer to array to assign to \a arrayToSet. + * \param [in,out] arrayToSet - the pointer to array to assign to. + */ void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) { if(newArray!=arrayToSet) @@ -4806,54 +7811,72 @@ void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) } } -DataArrayIntIterator *DataArrayInt::iterator() +DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception) { return new DataArrayIntIterator(this); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a + * given one. + * \param [in] val - the value to find within \a this. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not + * equal to a given one. + * \param [in] val - the value to ignore within \a this. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } + /*! - * This method expects that 'this' is allocated. If not an exception will be thrown. - * This method expect that the number of components is exactly equal to 1. If not an exception will be thrown. - * For each element in 'this' equal to 'oldValue' will take the value 'newValue'. - * @return number of elements impacted by the modification. + * Assigns \a newValue to all elements holding \a oldValue within \a this + * one-dimensional array. + * \param [in] oldValue - the value to replace. + * \param [in] newValue - the value to assign. + * \return int - number of replacements performed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !"); - checkAllocated(); int *start=getPointer(); int *end2=start+getNbOfElems(); int ret=0; @@ -4868,6 +7891,16 @@ int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::E return ret; } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to + * one of given values. + * \param [in] valsBg - an array of values to find within \a this array. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -4876,15 +7909,23 @@ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEn const int *cptr=getConstPointer(); std::vector res; int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not + * equal to any of given values. + * \param [in] valsBg - an array of values to ignore within \a this array. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -4893,13 +7934,11 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val const int *cptr=getConstPointer(); std::vector res; int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } /*! @@ -4916,6 +7955,7 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val */ int DataArrayInt::locateTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfCompo=getNumberOfComponents(); if(nbOfCompo==0) throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !"); @@ -4925,7 +7965,7 @@ int DataArrayInt::locateTuple(const std::vector& tupl) const throw(INTERP_K throw INTERP_KERNEL::Exception(oss.str().c_str()); } const int *cptr=getConstPointer(); - int nbOfVals=getNbOfElems(); + std::size_t nbOfVals=getNbOfElems(); for(const int *work=cptr;work!=cptr+nbOfVals;) { work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end()); @@ -4948,11 +7988,12 @@ int DataArrayInt::locateTuple(const std::vector& tupl) const throw(INTERP_K */ int DataArrayInt::search(const std::vector& vals) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); int nbOfCompo=getNumberOfComponents(); if(nbOfCompo!=1) throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !"); const int *cptr=getConstPointer(); - int nbOfVals=getNbOfElems(); + std::size_t nbOfVals=getNbOfElems(); const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end()); if(loc!=cptr+nbOfVals) return std::distance(cptr,loc); @@ -4967,6 +8008,7 @@ int DataArrayInt::search(const std::vector& vals) const throw(INTERP_KERNEL */ int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr=getConstPointer(); @@ -4985,15 +8027,39 @@ int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception) */ int DataArrayInt::locateValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); std::set vals2(vals.begin(),vals.end()); const int *cptr=getConstPointer(); int nbOfTuples=getNumberOfTuples(); - for(const int *w=cptr;w!=cptr+nbOfTuples;w++) - if(vals2.find(*w)!=vals2.end()) - return std::distance(cptr,w); - return -1; + for(const int *w=cptr;w!=cptr+nbOfTuples;w++) + if(vals2.find(*w)!=vals2.end()) + return std::distance(cptr,w); + return -1; +} + +/*! + * This method returns the number of values in \a this that are equals to input parameter \a value. + * This method only works for single component array. + * + * \return a value in [ 0, \c this->getNumberOfTuples() ) + * + * \throw If \a this is not allocated + * + */ +int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception) +{ + int ret=0; + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); + const int *vals=begin(); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i& tupl) const throw(INT return locateTuple(tupl)!=-1; } + /*! - * This method expects to be called when number of components of this is equal to one. - * This method returns true if it exists a tuple equal to \b value. - * If not any tuple contains \b value false is returned. - * \sa DataArrayInt::locateValue + * Returns \a true if a given value is present within \a this one-dimensional array. + * \param [in] value - the value to find within \a this array. + * \return bool - \a true in case if \a value is present within \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa locateValue() */ bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception) { @@ -5031,6 +8100,114 @@ bool DataArrayInt::presenceOfValue(const std::vector& vals) const throw(INT return locateValue(vals)!=-1; } +/*! + * Accumulates values of each component of \a this array. + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * by the caller, that is filled by this method with sum value for each + * component. + * \throw If \a this is not allocated. + */ +void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const int *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + std::fill(res,res+nbComps,0); + for(int i=0;i()); +} + +int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const int *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + if(compId<0 || compId>=nbComps) + throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !"); + int ret=0; + for(int i=0;igetNumberOfTuples). + * + * \param [in] bgOfIndex - begin (included) of the input index array. + * \param [in] endOfIndex - end (excluded) of the input index array. + * \return DataArrayInt * - the new instance having the same number of components than \a this. + * + * \throw If bgOfIndex or end is NULL. + * \throw If input index array is not ascendingly sorted. + * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples). + * \throw If std::distance(bgOfIndex,endOfIndex)==0. + */ +DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception) +{ + if(!bgOfIndex || !endOfIndex) + throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !"); + checkAllocated(); + int nbCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + int sz=(int)std::distance(bgOfIndex,endOfIndex); + if(sz<1) + throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !"); + sz--; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(sz,nbCompo); + const int *w=bgOfIndex; + if(*w<0 || *w>=nbOfTuples) + throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); + const int *srcPt=begin()+(*w)*nbCompo; + int *tmp=ret->getPointer(); + for(int i=0;i=w[0]) + { + for(int j=w[0];j=0 && j()); + else + { + std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted."; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number + * of tuples in the result array is a1->getNumberOfTuples() + a2->getNumberOfTuples() - + * offsetA2 and (2) + * the number of component in the result array is same as that of each of given arrays. + * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \param [in] offsetA2 - number of tuples of \a a2 to skip. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). + */ DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) { if(!a1 || !a2) @@ -5048,6 +8225,19 @@ DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt return ret; } +/*! + * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If getNumberOfComponents() of arrays within \a arr. + */ DataArrayInt *DataArrayInt::Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5065,17 +8255,25 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector& a throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !"); nbt+=(*it)->getNumberOfTuples(); } - DataArrayInt *ret=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbt,nbOfComp); int *pt=ret->getPointer(); for(it=a.begin();it!=a.end();it++) pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); ret->copyStringInfoFrom(*(a[0])); - return ret; + return ret.retn(); } +/*! + * Returns the maximal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the maximal value. + * \return int - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); int nbOfTuples=getNumberOfTuples(); @@ -5088,7 +8286,10 @@ int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception } /*! - * Idem to DataArrayInt::getMaxValue expect that here number of components can be >=1. + * Returns the maximal value within \a this array that is allowed to have more than + * one component. + * \return int - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. */ int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -5097,8 +8298,16 @@ int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) return *loc; } +/*! + * Returns the minimal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the minimal value. + * \return int - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); int nbOfTuples=getNumberOfTuples(); @@ -5111,7 +8320,10 @@ int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception } /*! - * Idem to DataArrayInt::getMinValue expect that here number of components can be >=1. + * Returns the minimal value within \a this array that is allowed to have more than + * one component. + * \return int - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. */ int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -5120,14 +8332,27 @@ int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception) return *loc; } +/*! + * Converts every value of \a this array to its absolute value. + * \throw If \a this is not allocated. + */ void DataArrayInt::abs() throw(INTERP_KERNEL::Exception) { checkAllocated(); int *ptr=getPointer(); - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(std::abs)); + declareAsNew(); } +/*! + * Apply a liner function to a given component of \a this array, so that + * an array element (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If \a this is not allocated. + */ void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5139,19 +8364,30 @@ void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exce declareAsNew(); } +/*! + * Apply a liner function to all elements of \a this array, so that + * an element _x_ becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If \a this is not allocated. + */ void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception) { checkAllocated(); int *ptr=getPointer(); - int nbOfElems=getNbOfElems(); - for(int i=0;i(),val)); declareAsNew(); } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes x % val . + * \param [in] val - the divisor used to modify array elements. + * \throw If \a this is not allocated. + * \throw If \a val <= 0. + */ void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception) { if(val<=0) throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !"); checkAllocated(); int *ptr=getPointer(); - int nbOfElems=getNbOfElems(); + std::size_t nbOfElems=getNbOfElems(); std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus(),val)); declareAsNew(); } @@ -5219,37 +8474,40 @@ void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception) * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that * this[*id] in [\b vmin,\b vmax) * - * \param [in] vmin begin of range. This value is included in range. - * \param [out] vmax end of range. This value is \b not included in range. + * \param [in] vmin begin of range. This value is included in range (included). + * \param [out] vmax end of range. This value is \b not included in range (excluded). * \return a newly allocated data array that the caller should deal with. */ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception) { + checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); const int *cptr=getConstPointer(); - std::vector res; + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;i=vmin && *cptralloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } /*! - * This method applies the operation 'numerator%x' for each element 'x' in 'this'. - * If there is a value in 'this' exactly equals or lower than 0. an exception is thrown. - * Warning if presence of null this is modified for each values previous than place where exception was thrown ! + * Modify all elements of \a this array, so that + * an element _x_ becomes val % x . + * \warning If an exception is thrown because of presence of an element <= 0 in \a this + * array, all elements processed before detection of the zero element remain + * modified. + * \param [in] val - the divident used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to or less than 0 in \a this array. */ void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception) { checkAllocated(); int *ptr=getPointer(); - int nbOfElems=getNbOfElems(); - for(int i=0;i0) { @@ -5265,6 +8523,85 @@ void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes val ^ x . + * \param [in] val - the value used to apply pow on all array elements. + * \throw If \a this is not allocated. + * \throw If \a val < 0. + */ +void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(val<0) + throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !"); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + if(val==0) + { + std::fill(ptr,ptr+nbOfElems,1.); + return ; + } + for(std::size_t i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptr;j++) + tmp*=val; + *ptr=tmp; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If any given array is not allocated. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + */ DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { std::vector arr(2); @@ -5272,6 +8609,21 @@ DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) return Meld(arr); } +/*! + * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If any given array is not allocated. + * \throw If getNumberOfTuples() of arrays within \a arr is different. + */ DataArrayInt *DataArrayInt::Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5314,13 +8666,28 @@ DataArrayInt *DataArrayInt::Meld(const std::vector& arr) t } /*! - * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'. - * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns - * for each group the familyId it contains. If an id so that id + * and the result array contains IDs of families [ 1,3,3,0,2 ].
Note a family ID 0 which + * stands for the element #3 which is in none of groups. * - * @param groups in arrays specifying ids of each groups. - * @param newNb specifies size of whole set. Must be at least equal to max eltid in 'groups'. - * @return an array of size newNb specifying fid of each item. + * \param [in] groups - sequence of groups of element IDs. + * \param [in] newNb - total number of elements; it must be more than max ID of element + * in \a groups. + * \param [out] fidsOfGroups - IDs of families the elements of each group belong to. + * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families + * each element with ID from range [0, \a newNb ) belongs to. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ). */ DataArrayInt *DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception) { @@ -5336,12 +8703,12 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vector::const_iterator iter=groups2.begin();iter!=groups2.end();iter++) { const int *ptr=(*iter)->getConstPointer(); - int nbOfElem=(*iter)->getNbOfElems(); + std::size_t nbOfElem=(*iter)->getNbOfElems(); int sfid=fid; for(int j=0;j=0 && ptr[i] tmp; const int *ptr=(*iter)->getConstPointer(); - int nbOfElem=(*iter)->getNbOfElems(); + std::size_t nbOfElem=(*iter)->getNbOfElems(); for(const int *p=ptr;p!=ptr+nbOfElem;p++) tmp.insert(retPtr[*p]); fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end()); } - ret->incrRef(); - return ret; + return ret.retn(); } +/*! + * Returns a new DataArrayInt which contains all elements of given one-dimensional + * arrays. The result array does not contain any duplicates and its values + * are sorted in ascending order. + * \param [in] arr - sequence of DataArrayInt's to unite. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If any \a arr[i] is not allocated. + * \throw If \a arr[i]->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) if(*it4) a.push_back(*it4); - int valm=std::numeric_limits::max(); for(std::vector::const_iterator it=a.begin();it!=a.end();it++) { (*it)->checkAllocated(); if((*it)->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !"); - int tmp1; - valm=std::min((*it)->getMinValue(tmp1),valm); } - if(valm<0) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !"); // std::set r; for(std::vector::const_iterator it=a.begin();it!=a.end();it++) @@ -5409,23 +8780,28 @@ DataArrayInt *DataArrayInt::BuildUnion(const std::vector& return ret; } +/*! + * Returns a new DataArrayInt which contains elements present in each of given one-dimensional + * arrays. The result array does not contain any duplicates and its values + * are sorted in ascending order. + * \param [in] arr - sequence of DataArrayInt's to intersect. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If any \a arr[i] is not allocated. + * \throw If \a arr[i]->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) if(*it4) a.push_back(*it4); - int valm=std::numeric_limits::max(); for(std::vector::const_iterator it=a.begin();it!=a.end();it++) { (*it)->checkAllocated(); if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !"); - int tmp1; - valm=std::min((*it)->getMinValue(tmp1),valm); + throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !"); } - if(valm<0) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !"); // std::set r; for(std::vector::const_iterator it=a.begin();it!=a.end();it++) @@ -5448,6 +8824,18 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vectorgetNumberOfComponents() != 1. + * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a + * nbOfElement ). + */ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5472,6 +8860,19 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_ return ret; } +/*! + * Returns a new DataArrayInt containing elements of \a this one-dimensional missing + * from an \a other one-dimensional array. + * \param [in] other - a DataArrayInt containing elements not to include in the result array. + * \return DataArrayInt * - a new instance of DataArrayInt with one component. The + * caller is to delete this array using decrRef() as it is no more needed. + * \throw If \a other is NULL. + * \throw If \a other is not allocated. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa DataArrayInt::buildSubstractionOptimized() + */ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { if(!other) @@ -5496,6 +8897,45 @@ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const t return ret; } +/*! + * \a this is expected to have one component and to be sorted ascendingly (as for \a other). + * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead. + * + * \param [in] other an array with one component and expected to be sorted ascendingly. + * \ret list of ids in \a this but not in \a other. + * \sa DataArrayInt::buildSubstraction + */ +DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) +{ + static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !"; + if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !"); + checkAllocated(); other->checkAllocated(); + if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); + const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + for(;work1!=pt1End;work1++) + { + if(work2!=pt2End && *work1==*work2) + work2++; + else + ret->pushBackSilent(*work1); + } + return ret.retn(); +} + + +/*! + * Returns a new DataArrayInt which contains all elements of \a this and a given + * one-dimensional arrays. The result array does not contain any duplicates + * and its values are sorted in ascending order. + * \param [in] other - an array to unite with \a this one. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this or \a other is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { std::vectorarrs(2); @@ -5503,6 +8943,18 @@ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(IN return BuildUnion(arrs); } + +/*! + * Returns a new DataArrayInt which contains elements present in both \a this and a given + * one-dimensional arrays. The result array does not contain any duplicates + * and its values are sorted in ascending order. + * \param [in] other - an array to intersect with \a this one. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this or \a other is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { std::vectorarrs(2); @@ -5530,17 +8982,27 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(std::distance(data,last),1); std::copy(data,last,ret->getPointer()); - ret->incrRef(); - return ret; + return ret.retn(); } /*! - * This method could be usefull for returned DataArrayInt marked as index. Some methods that generate such DataArrayInt instances: - * - ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity - * - ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex - * This method makes the assumption that 'this' is allocated and has exactly one component and 2 or more tuples. If not an exception is thrown. - * This method retrives a newly created DataArrayInt instance with 1 component and this->getNumberOfTuples()-1 tuples. - * If this contains [1,3,6,7,7,9,15] -> returned array will contain [2,3,1,0,2,6]. + * Returns a new DataArrayInt which contains size of every of groups described by \a this + * "index" array. Such "index" array is returned for example by + * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity + * "MEDCouplingUMesh::buildDescendingConnectivity" and + * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex + * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. + * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples + * equals to \a this->getNumberOfComponents() - 1, and number of components is 1. + * The caller is to delete this array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 2. + * + * \b Example:
+ * - this contains [1,3,6,7,7,9,15] + * - result array contains [2,3,1,0,2,6], + * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc. */ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception) { @@ -5559,10 +9021,21 @@ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Excepti } /*! - * This method performs the work on itself. This method works on array with number of component equal to one and allocated. If not an exception is thrown. - * This method conserves the number of tuples and number of components (1). No reallocation is done. - * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11]. For each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. - * This could be usefull for allToAllV in MPI with contiguous policy. + * Modifies \a this one-dimensional array so that value of each element \a x + * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$. + * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples + * and components remains the same.
+ * This method is useful for allToAllV in MPI with contiguous policy. This method + * differs from computeOffsets2() in that the number of tuples is \b not changed by + * this one. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \b Example:
+ * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11]
+ * Note that the last element 19 = 11 + 8 is missing because size of \a this + * array is retained and thus there is no space to store the last element. */ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) { @@ -5584,12 +9057,20 @@ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) declareAsNew(); } + /*! - * Idem DataArrayInt::computeOffsets method execpt that 'this' changes its number of tuples. - * After the call in case of success new number of tuples is equal to old number of tuples +1. - * The content in 'this' for the first old number of tuples is exactly the same than those given by - * DataArrayInt::computeOffsets method. - * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11,19]. + * Modifies \a this one-dimensional array so that value of each element \a x + * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$. + * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number + * components remains the same and number of tuples is inceamented by one.
+ * This method is useful for allToAllV in MPI with contiguous policy. This method + * differs from computeOffsets() in that the number of tuples is changed by this one. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \b Example:
+ * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11,19]
*/ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) { @@ -5597,22 +9078,94 @@ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !"); int nbOfTuples=getNumberOfTuples(); - int *ret=new int[nbOfTuples+1]; + int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int)); if(nbOfTuples==0) return ; const int *work=getConstPointer(); ret[0]=0; for(int i=0;igetNumberOfTuples()-1 tuples. - * If 'this' contains [0,2,3] and 'offsets' [0,3,6,10,14,20] the returned array will contain [0,1,2,6,7,8,9,10,11,12,13] + * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows. + * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component + * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds). + * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds + * filling completely one of the ranges in \a this. + * + * \param [in] listOfIds a list of ids that has to be sorted ascendingly. + * \param [out] rangeIdsFetched the range ids fetched + * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So + * \a idsInInputListThatFetch is a part of input \a listOfIds. + * + * \sa DataArrayInt::computeOffsets2 + * + * \b Example:
+ * - \a this : [0,3,7,9,15,18] + * - \a listOfIds contains [0,1,2,3,7,8,15,16,17] + * - \a rangeIdsFetched result array: [0,2,4] + * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17] + * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch. + *
+ */ +void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception) +{ + if(!listOfIds) + throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !"); + listOfIds->checkAllocated(); checkAllocated(); + if(listOfIds->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !"); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !"); + MEDCouplingAutoRefCountObjectPtr ret0=DataArrayInt::New(); ret0->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc(0,1); + const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1); + const int *tupPtr(listOfIds->begin()),*offPtr(offBg); + while(tupPtr!=tupEnd && offPtr!=offEnd) + { + if(*tupPtr==*offPtr) + { + int i=offPtr[0]; + while(ipushBackSilent((int)std::distance(offBg,offPtr)); + ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr); + offPtr++; + } + } + else + { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; } + } + rangeIdsFetched=ret0.retn(); + idsInInputListThatFetch=ret1.retn(); +} + +/*! + * Returns a new DataArrayInt whose contents is computed from that of \a this and \a + * offsets arrays as follows. \a offsets is a one-dimensional array considered as an + * "index" array of a "iota" array, thus, whose each element gives an index of a group + * beginning within the "iota" array. And \a this is a one-dimensional array + * considered as a selector of groups described by \a offsets to include into the result array. + * \throw If \a offsets is NULL. + * \throw If \a offsets is not allocated. + * \throw If \a offsets->getNumberOfComponents() != 1. + * \throw If \a offsets is not monotonically increasing. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any element of \a this is not a valid index for \a offsets array. + * + * \b Example:
+ * - \a this: [0,2,3] + * - \a offsets: [0,3,6,10,14,20] + * - result array: [0,1,2,6,7,8,9,10,11,12,13] ==
+ * \c range(0,3) + \c range(6,10) + \c range(10,14) ==
+ * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + + * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + + * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ]) */ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception) { @@ -5661,8 +9214,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets for(int j=0;jincrRef(); - return ret; + return ret.retn(); } /*! @@ -5711,8 +9263,7 @@ DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5761,8 +9312,7 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -5790,20 +9340,22 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN *retPtr=val; } ret->copyStringInfoFrom(*this); - ret->incrRef(); - return ret; + return ret.retn(); } /*! * This method returns all different values found in \a this. This method throws if \a this has not been allocated. * But the number of components can be different from one. + * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this. */ -std::set DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception) +DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception) { checkAllocated(); std::set ret; ret.insert(begin(),end()); - return ret; + MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); + std::copy(ret.begin(),ret.end(),ret2->getPointer()); + return ret2.retn(); } /*! @@ -5842,6 +9394,31 @@ std::vector DataArrayInt::partitionByDifferentValues(std::vector return ret; } +/*! + * Returns a new DataArrayInt that is a sum of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2, + * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to sum up. + * \param [in] a2 - another array to sum up. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -5909,15 +9486,32 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - ret->incrRef(); - return ret; + return ret.retn(); } +/*! + * Adds values of another DataArrayInt to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is added to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] += _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] += _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] += _a2_ [ 0, j ]. + * + * \param [in] other - an array to add to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual !"; + checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -5955,6 +9549,31 @@ void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exce declareAsNew(); } +/*! + * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a subtraction of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to subtract from. + * \param [in] a2 - an array to subtract. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -5971,8 +9590,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -5984,8 +9602,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6003,8 +9620,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6013,11 +9629,29 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt } } +/*! + * Subtract values of another DataArrayInt from values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is subtracted from the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] -= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] -= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] -= _a2_ [ 0, j ]. + * + * \param [in] other - an array to subtract from \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual !"; + checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -6050,6 +9684,31 @@ void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL declareAsNew(); } +/*! + * Returns a new DataArrayInt that is a product of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a product of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a factor array. + * \param [in] a2 - another factor array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6117,15 +9776,33 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt } else throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - ret->incrRef(); - return ret; + return ret.retn(); } + +/*! + * Multiply values of another DataArrayInt to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is multiplied to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] *= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] *= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] *= _a2_ [ 0, j ]. + * + * \param [in] other - an array to multiply to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !"; + checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -6163,6 +9840,33 @@ void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL: declareAsNew(); } + +/*! + * Returns a new DataArrayInt that is a division of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \warning No check of division by zero is performed! + * \param [in] a1 - a numerator array. + * \param [in] a2 - a denominator array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6179,8 +9883,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -6192,8 +9895,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6211,8 +9913,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6221,11 +9922,30 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a } } +/*! + * Divide values of \a this array by values of another DataArrayInt. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] /= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] /= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] /= _a2_ [ 0, j ]. + * + * \warning No check of division by zero is performed! + * \param [in] other - an array to divide \a this one by. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !"; + checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -6263,6 +9983,33 @@ void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::E declareAsNew(); } + +/*! + * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \warning No check of division by zero is performed! + * \param [in] a1 - a dividend array. + * \param [in] a2 - a divisor array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6279,8 +10026,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else if(nbOfComp2==1) { @@ -6292,8 +10038,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * for(int i=0;i(),a2Ptr[i])); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6311,8 +10056,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * for(int i=0;i()); ret->copyStringInfoFrom(*a1); - ret->incrRef(); - return ret; + return ret.retn(); } else { @@ -6321,11 +10065,30 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * } } +/*! + * Modify \a this array so that each value becomes a modulus of division of this value by + * a value of another DataArrayInt. There are 3 valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] %= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] %= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] %= _a2_ [ 0, j ]. + * + * \warning No check of division by zero is performed! + * \param [in] other - a divisor array. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !"); const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !"; + checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); int nbOfComp=getNumberOfComponents(); @@ -6363,26 +10126,144 @@ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL:: declareAsNew(); } +/*! + * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3 + * valid cases. + * + * \param [in] a1 - an array to pow up. + * \param [in] a2 - another array to sum up. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. + * \throw If there is a negative value in \a a2. + */ +DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); + const int *ptr1(a1->begin()),*ptr2(a2->begin()); + int *ptr=ret->getPointer(); + for(int i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptr2;j++) + tmp*=*ptr1; + *ptr=tmp; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Apply pow on values of another DataArrayInt to values of \a this one. + * + * \param [in] other - an array to pow to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() + * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1 + * \throw If there is a negative value in \a other. + */ +void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !"); + int nbOfTuple=getNumberOfTuples(); + int nbOfTuple2=other->getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !"); + int *ptr=getPointer(); + const int *ptrc=other->begin(); + for(int i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptrc;j++) + tmp*=*ptr; + *ptr=tmp; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * Returns a C array which is a renumbering map in "Old to New" mode for the input array. + * This map, if applied to \a start array, would make it sorted. For example, if + * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is + * [5,6,0,3,2,7,1,4]. + * \param [in] start - pointer to the first element of the array for which the + * permutation map is computed. + * \param [in] end - pointer specifying the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \return int * - the result permutation array that the caller is to delete as it is no + * more needed. + * \throw If there are equal values in the input array. + */ int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end) { std::size_t sz=std::distance(start,end); - int *ret=new int[sz]; + int *ret=(int *)malloc(sz*sizeof(int)); int *work=new int[sz]; std::copy(start,end,work); std::sort(work,work+sz); if(std::unique(work,work+sz)!=work+sz) { delete [] work; - delete [] ret; + free(ret); throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !"); } + std::map m; + for(int *workPt=work;workPt!=work+sz;workPt++) + m[*workPt]=(int)std::distance(work,workPt); int *iter2=ret; for(const int *iter=start;iter!=end;iter++,iter2++) - *iter2=(int)std::distance(work,std::find(work,work+sz,*iter)); + *iter2=m[*iter]; delete [] work; return ret; } +/*! + * Returns a new DataArrayInt containing an arithmetic progression + * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step ) + * function. + * \param [in] begin - the start value of the result sequence. + * \param [in] end - limiting value, so that every value of the result array is less than + * \a end. + * \param [in] step - specifies the increment or decrement. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a step == 0. + * \throw If \a end < \a begin && \a step > 0. + * \throw If \a end > \a begin && \a step < 0. + */ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception) { int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range"); @@ -6399,8 +10280,7 @@ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KER for(int i=begin;i>end;i+=step,ptr++) *ptr=i; } - ret->incrRef(); - return ret; + return ret.retn(); } /*! @@ -6494,7 +10374,7 @@ DataArrayIntIterator::~DataArrayIntIterator() _da->decrRef(); } -DataArrayIntTuple *DataArrayIntIterator::nextt() +DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception) { if(_tuple_id<_nb_tuple) { @@ -6511,7 +10391,7 @@ DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo { } -std::string DataArrayIntTuple::repr() const +std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception) { std::ostringstream oss; oss << "("; for(int i=0;i<_nb_of_compo-1;i++) diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 6b8b5853f..64727c30c 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -25,9 +25,8 @@ #include "MEDCouplingTimeLabel.hxx" #include "MEDCouplingRefCountObject.hxx" #include "InterpKernelException.hxx" -#include "BBTree.txx" +#include "BBTreePts.txx" -#include #include #include #include @@ -44,7 +43,7 @@ namespace ParaMEDMEM void setInternal(T *pointer); void setExternal(const T *pointer); const T *getConstPointer() const { if(_internal) return _internal; else return _external; } - const T *getConstPointerLoc(int offset) const { if(_internal) return _internal+offset; else return _external+offset; } + const T *getConstPointerLoc(std::size_t offset) const { if(_internal) return _internal+offset; else return _external+offset; } T *getPointer() { if(_internal) return _internal; if(_external) throw INTERP_KERNEL::Exception("Trying to write on an external pointer."); else return 0; } private: T *_internal; @@ -55,82 +54,124 @@ namespace ParaMEDMEM class MemArray { public: - MemArray():_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) { } + typedef void (*Deallocator)(void *,void *); + public: + MemArray():_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) { } MemArray(const MemArray& other); bool isNull() const { return _pointer.isNull(); } - const T *getConstPointerLoc(int offset) const { return _pointer.getConstPointerLoc(offset); } + const T *getConstPointerLoc(std::size_t offset) const { return _pointer.getConstPointerLoc(offset); } const T *getConstPointer() const { return _pointer.getConstPointer(); } + std::size_t getNbOfElem() const { return _nb_of_elem; } + std::size_t getNbOfElemAllocated() const { return _nb_of_elem_alloc; } T *getPointer() { return _pointer.getPointer(); } MemArray &operator=(const MemArray& other); - T operator[](int id) const { return _pointer.getConstPointer()[id]; } - T& operator[](int id) { return _pointer.getPointer()[id]; } + T operator[](std::size_t id) const { return _pointer.getConstPointer()[id]; } + T& operator[](std::size_t id) { return _pointer.getPointer()[id]; } bool isEqual(const MemArray& other, T prec, std::string& reason) const; void repr(int sl, std::ostream& stream) const; + bool reprHeader(int sl, std::ostream& stream) const; void reprZip(int sl, std::ostream& stream) const; void fillWithValue(const T& val); T *fromNoInterlace(int nbOfComp) const; T *toNoInterlace(int nbOfComp) const; void sort(bool asc); - void reverse(); - void alloc(int nbOfElements) throw(INTERP_KERNEL::Exception); - void reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception); - void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem); - void useExternalArrayWithRWAccess(const T *array, int nbOfElem); - void writeOnPlace(int id, T element0, const T *others, int sizeOfOthers); + void reverse(int nbOfComp); + void alloc(std::size_t nbOfElements) throw(INTERP_KERNEL::Exception); + void reserve(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception); + void reAlloc(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception); + void useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem); + void useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem); + void writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers); + template + void insertAtTheEnd(InputIterator first, InputIterator last); + void pushBack(T elem) throw(INTERP_KERNEL::Exception); + T popBack() throw(INTERP_KERNEL::Exception); + void pack() const; + bool isDeallocatorCalled() const { return _ownership; } + Deallocator getDeallocator() const { return _dealloc; } + void setSpecificDeallocator(Deallocator dealloc) { _dealloc=dealloc; } + void setParameterForDeallocator(void *param) { _param_for_deallocator=param; } + void *getParameterForDeallocator() const { return _param_for_deallocator; } + void destroy(); ~MemArray() { destroy(); } + public: + static void CPPDeallocator(void *pt, void *param); + static void CDeallocator(void *pt, void *param); private: - void destroy(); - static void destroyPointer(T *pt, DeallocType type); + static void destroyPointer(T *pt, Deallocator dealloc, void *param); + static Deallocator BuildFromType(DeallocType type) throw(INTERP_KERNEL::Exception); private: - int _nb_of_elem; + std::size_t _nb_of_elem; + std::size_t _nb_of_elem_alloc; bool _ownership; MEDCouplingPointer _pointer; - DeallocType _dealloc; + Deallocator _dealloc; + void *_param_for_deallocator; }; + class DataArrayInt; + class DataArray : public RefCountObject, public TimeLabel { public: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT void setName(const char *name); MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string getName() const { return _name; } MEDCOUPLING_EXPORT const std::vector &getInfoOnComponents() const { return _info_on_compo; } MEDCOUPLING_EXPORT std::vector &getInfoOnComponents() { return _info_on_compo; } MEDCOUPLING_EXPORT void setInfoOnComponents(const std::vector& info) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT std::vector getVarsOnComponent() const; - MEDCOUPLING_EXPORT std::vector getUnitsOnComponent() const; + MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::vector getVarsOnComponent() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::vector getUnitsOnComponent() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); } - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; } - MEDCOUPLING_EXPORT int getNbOfElems() const { return ((int)_info_on_compo.size())*_nb_of_tuples; } + MEDCOUPLING_EXPORT virtual bool isAllocated() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void checkAllocated() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual DataArray *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual DataArray *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) = 0; MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT virtual void reprCppStream(const char *varName, std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT virtual void reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception) = 0; protected: - DataArray():_nb_of_tuples(-1) { } + DataArray() { } + ~DataArray() { } protected: static void CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception); static void CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception); static void CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception); protected: - int _nb_of_tuples; std::string _name; std::vector _info_on_compo; }; @@ -146,16 +187,24 @@ namespace ParaMEDMEM { public: MEDCOUPLING_EXPORT static DataArrayDouble *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; + MEDCOUPLING_EXPORT bool isAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfTuples() const throw(INTERP_KERNEL::Exception) { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT double doubleValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackSilent(double val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double popBackSilent() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithValue(double val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void iota(double init=0.) throw(INTERP_KERNEL::Exception); @@ -164,40 +213,43 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT std::string repr() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::string reprZip() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; - //!alloc or useArray should have been called before. + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *toNoInterlace() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const; + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception); 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 end2, int step) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) 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 void transpose() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); @@ -205,28 +257,32 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*((int)_info_on_compo.size())),_mem.getConstPointerLoc((tupleId+1)*((int)_info_on_compo.size())),res); } - MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*((int)_info_on_compo.size())+compoId]; } + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const throw(INTERP_KERNEL::Exception) { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } + MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } MEDCOUPLING_EXPORT double back() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*((int)_info_on_compo.size())+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*((int)_info_on_compo.size())+compoId]=newVal; } - MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); } + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } + MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT double *getPointer() throw(INTERP_KERNEL::Exception) { return _mem.getPointer(); } MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet); - MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT DataArrayDoubleIterator *iterator(); - MEDCOUPLING_EXPORT const double *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const double *end() const { return getConstPointer()+getNbOfElems(); } - MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } + MEDCOUPLING_EXPORT const double *getConstPointer() const throw(INTERP_KERNEL::Exception) { return _mem.getConstPointer(); } + MEDCOUPLING_EXPORT DataArrayDoubleIterator *iterator() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT const double *begin() const throw(INTERP_KERNEL::Exception) { return getConstPointer(); } + MEDCOUPLING_EXPORT const double *end() const throw(INTERP_KERNEL::Exception) { return getConstPointer()+getNbOfElems(); } + MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + template + void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void writeOnPlace(std::size_t id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT void checkNoNullValues() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMaxValueInArray() const throw(INTERP_KERNEL::Exception); @@ -234,11 +290,14 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT double getMinValueInArray() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int count(double value, double eps) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double getAverageValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double norm2() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double normMax() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void accumulate(double *res) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT double accumulate(int compId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception); @@ -251,6 +310,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); @@ -258,6 +318,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyInv(double numerator) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyPow(double val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyRPow(double val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *negate() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception); @@ -283,8 +345,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - //! nothing to do here because this class does not aggregate any TimeLabel instance. + MEDCOUPLING_EXPORT static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } public: MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; @@ -292,11 +357,14 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); public: template - void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const; + void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const; + template + static void FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res); template - static void FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double *pos, int nbOfTuples, double eps, - std::vector& c, std::vector& cI); + static void FindTupleIdsNearTuplesAlg(const BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, + DataArrayInt *c, DataArrayInt *cI); private: + ~DataArrayDouble() { } DataArrayDouble() { } private: MemArray _mem; @@ -309,7 +377,7 @@ namespace ParaMEDMEM public: DataArrayDoubleIterator(DataArrayDouble *da); ~DataArrayDoubleIterator(); - DataArrayDoubleTuple *nextt(); + DataArrayDoubleTuple *nextt() throw(INTERP_KERNEL::Exception); private: DataArrayDouble *_da; double *_pt; @@ -322,7 +390,7 @@ namespace ParaMEDMEM { public: DataArrayDoubleTuple(double *pt, int nbOfComp); - std::string repr() const; + std::string repr() const throw(INTERP_KERNEL::Exception); int getNumberOfCompo() const { return _nb_of_compo; } const double *getConstPointer() const { return _pt; } double *getPointer() { return _pt; } @@ -339,58 +407,72 @@ namespace ParaMEDMEM { public: MEDCOUPLING_EXPORT static DataArrayInt *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; + MEDCOUPLING_EXPORT bool isAllocated() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfTuples() const throw(INTERP_KERNEL::Exception) { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; MEDCOUPLING_EXPORT int intValue() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getHashCode() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackSilent(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int popBackSilent() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void sort(bool asc=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithValue(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void iota(int init=0) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT std::string repr() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::string reprZip() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd, DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; - //!alloc or useArray should have been called before. + MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *toNoInterlace() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const throw(INTERP_KERNEL::Exception); 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 *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isIdentity() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isUniform(int val) const throw(INTERP_KERNEL::Exception); @@ -398,7 +480,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void transpose() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); @@ -407,21 +489,23 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*((int)_info_on_compo.size())),_mem.getConstPointerLoc((tupleId+1)*((int)_info_on_compo.size())),res); } - MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*((int)_info_on_compo.size())+compoId]; } + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const throw(INTERP_KERNEL::Exception) { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } + MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { return _mem[tupleId*_info_on_compo.size()+compoId]; } MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int back() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*((int)_info_on_compo.size())+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*((int)_info_on_compo.size())+compoId]=newVal; } - MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); } + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } + MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT int *getPointer() throw(INTERP_KERNEL::Exception) { return _mem.getPointer(); } MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet); - MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT DataArrayIntIterator *iterator(); - MEDCOUPLING_EXPORT const int *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const int *end() const { return getConstPointer()+getNbOfElems(); } + MEDCOUPLING_EXPORT const int *getConstPointer() const throw(INTERP_KERNEL::Exception) { return _mem.getConstPointer(); } + MEDCOUPLING_EXPORT DataArrayIntIterator *iterator() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT const int *begin() const throw(INTERP_KERNEL::Exception) { return getConstPointer(); } + MEDCOUPLING_EXPORT const int *end() const throw(INTERP_KERNEL::Exception) { return getConstPointer()+getNbOfElems(); } MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(int val) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception); @@ -434,6 +518,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int count(int value) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void accumulate(int *res) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int accumulate(int compId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMaxValueInArray() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); @@ -446,6 +534,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void applyDivideBy(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyModulus(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyRModulus(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyPow(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyRPow(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception); @@ -456,21 +546,25 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *deltaShiftIndex() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void computeOffsets() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void computeOffsets2() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT std::set getDifferentValues() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } + MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + template + void insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void writeOnPlace(std::size_t id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); @@ -481,8 +575,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - //! nothing to do here because this class does not aggregate any TimeLabel instance. + MEDCOUPLING_EXPORT static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } public: MEDCOUPLING_EXPORT static int *CheckAndPreparePermutation(const int *start, const int *end); MEDCOUPLING_EXPORT static DataArrayInt *Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception); @@ -492,6 +589,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector& tinyInfoI); MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); private: + ~DataArrayInt() { } DataArrayInt() { } private: MemArray _mem; @@ -504,7 +602,7 @@ namespace ParaMEDMEM public: DataArrayIntIterator(DataArrayInt *da); ~DataArrayIntIterator(); - DataArrayIntTuple *nextt(); + DataArrayIntTuple *nextt() throw(INTERP_KERNEL::Exception); private: DataArrayInt *_da; int *_pt; @@ -517,7 +615,7 @@ namespace ParaMEDMEM { public: DataArrayIntTuple(int *pt, int nbOfComp); - std::string repr() const; + std::string repr() const throw(INTERP_KERNEL::Exception); int getNumberOfCompo() const { return _nb_of_compo; } const int *getConstPointer() const { return _pt; } int *getPointer() { return _pt; } @@ -527,6 +625,250 @@ namespace ParaMEDMEM int *_pt; int _nb_of_compo; }; + + class DataArrayChar : public DataArray + { + public: + MEDCOUPLING_EXPORT virtual DataArrayChar *buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception) = 0; + MEDCOUPLING_EXPORT virtual DataArrayChar *deepCpy() const = 0; + MEDCOUPLING_EXPORT bool isAllocated() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkAllocated() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int getNumberOfTuples() const throw(INTERP_KERNEL::Exception) { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; + MEDCOUPLING_EXPORT int getHashCode() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool empty() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void cpyFrom(const DataArrayChar& other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackSilent(char val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pushBackValsSilent(const char *valsBg, const char *valsEnd) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char popBackSilent() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void pack() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception) { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void fillWithValue(char val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::string repr() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::string reprZip() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *renumber(const int *old2New) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId2(int bg, int end, int step) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isUniform(char val) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void meldWith(const DataArrayChar *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void getTuple(int tupleId, char *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } + MEDCOUPLING_EXPORT char getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + MEDCOUPLING_EXPORT char getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char back() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } + MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT char *getPointer() { return _mem.getPointer(); } + MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); } + MEDCOUPLING_EXPORT const char *begin() const throw(INTERP_KERNEL::Exception) { return getConstPointer(); } + MEDCOUPLING_EXPORT const char *end() const throw(INTERP_KERNEL::Exception) { return getConstPointer()+getNbOfElems(); } + MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(char val) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(char val) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int search(const std::vector& vals) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int locateTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int locateValue(char value) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT int locateValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool presenceOfValue(char value) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char getMaxValueInArray() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT char getMinValueInArray() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2); + MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayChar *Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } + public: + //MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; + //MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; + //MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector& tinyInfoI); + //MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); + protected: + DataArrayChar() { } + protected: + MemArray _mem; + }; + + class DataArrayByteIterator; + + class DataArrayByte : public DataArrayChar + { + public: + MEDCOUPLING_EXPORT static DataArrayByte *New(); + MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayByteIterator *iterator(); + MEDCOUPLING_EXPORT DataArrayByte *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayByte *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT char byteValue() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + private: + ~DataArrayByte() { } + DataArrayByte() { } + }; + + class DataArrayByteTuple; + + class MEDCOUPLING_EXPORT DataArrayByteIterator + { + public: + DataArrayByteIterator(DataArrayByte *da); + ~DataArrayByteIterator(); + DataArrayByteTuple *nextt() throw(INTERP_KERNEL::Exception); + private: + DataArrayByte *_da; + char *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class MEDCOUPLING_EXPORT DataArrayByteTuple + { + public: + DataArrayByteTuple(char *pt, int nbOfComp); + std::string repr() const throw(INTERP_KERNEL::Exception); + int getNumberOfCompo() const { return _nb_of_compo; } + const char *getConstPointer() const { return _pt; } + char *getPointer() { return _pt; } + char byteValue() const throw(INTERP_KERNEL::Exception); + DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + private: + char *_pt; + int _nb_of_compo; + }; + + class DataArrayAsciiCharIterator; + + class DataArrayAsciiChar : public DataArrayChar + { + public: + MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(); + MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::string& st) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::vector& vst, char defaultChar) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayAsciiCharIterator *iterator(); + MEDCOUPLING_EXPORT DataArrayAsciiChar *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayAsciiChar *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT char asciiCharValue() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + private: + ~DataArrayAsciiChar() { } + DataArrayAsciiChar() { } + DataArrayAsciiChar(const std::string& st) throw(INTERP_KERNEL::Exception); + DataArrayAsciiChar(const std::vector& vst, char defaultChar) throw(INTERP_KERNEL::Exception); + }; + + class DataArrayAsciiCharTuple; + + class MEDCOUPLING_EXPORT DataArrayAsciiCharIterator + { + public: + DataArrayAsciiCharIterator(DataArrayAsciiChar *da); + ~DataArrayAsciiCharIterator(); + DataArrayAsciiCharTuple *nextt() throw(INTERP_KERNEL::Exception); + private: + DataArrayAsciiChar *_da; + char *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class MEDCOUPLING_EXPORT DataArrayAsciiCharTuple + { + public: + DataArrayAsciiCharTuple(char *pt, int nbOfComp); + std::string repr() const throw(INTERP_KERNEL::Exception); + int getNumberOfCompo() const { return _nb_of_compo; } + const char *getConstPointer() const { return _pt; } + char *getPointer() { return _pt; } + char asciiCharValue() const throw(INTERP_KERNEL::Exception); + DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + private: + char *_pt; + int _nb_of_compo; + }; + + template + void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception) + { + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(first,last); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(first,last); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::insertAtTheEnd : not available for DataArrayDouble with number of components different than 1 !"); + } + + template + void DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last) throw(INTERP_KERNEL::Exception) + { + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(first,last); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(first,last); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::insertAtTheEnd : not available for DataArrayInt with number of components different than 1 !"); + } } #endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index e569249d8..39030643d 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -17,6 +17,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // Author : Anthony Geay (CEA/DEN) + #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ @@ -26,6 +27,7 @@ #include "InterpolationUtils.hxx" #include +#include #include namespace ParaMEDMEM @@ -45,47 +47,94 @@ namespace ParaMEDMEM } template - MemArray::MemArray(const MemArray& other):_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) + MemArray::MemArray(const MemArray& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) { if(!other._pointer.isNull()) { - T *pointer=new T[other._nb_of_elem]; + _nb_of_elem_alloc=other._nb_of_elem; + T *pointer=(T*)malloc(_nb_of_elem_alloc*sizeof(T)); std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer); - useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem); + useArray(pointer,true,C_DEALLOC,other._nb_of_elem); } } template - void MemArray::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem) + void MemArray::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem) { _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; destroy(); if(ownership) _pointer.setInternal(const_cast(array)); else _pointer.setExternal(array); _ownership=ownership; - _dealloc=type; + _dealloc=BuildFromType(type); } template - void MemArray::useExternalArrayWithRWAccess(const T *array, int nbOfElem) + void MemArray::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem) { _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; destroy(); _pointer.setInternal(const_cast(array)); _ownership=false; - _dealloc=CPP_DEALLOC; + _dealloc=CPPDeallocator; } template - void MemArray::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers) + void MemArray::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers) { - if(id+sizeOfOthers>=_nb_of_elem) - reAlloc(2*_nb_of_elem+sizeOfOthers+1); + if(id+sizeOfOthers>=_nb_of_elem_alloc) + reserve(2*_nb_of_elem+sizeOfOthers+1); T *pointer=_pointer.getPointer(); pointer[id]=element0; std::copy(others,others+sizeOfOthers,pointer+id+1); + _nb_of_elem=std::max(_nb_of_elem,id+sizeOfOthers+1); + } + + template + template + void MemArray::insertAtTheEnd(InputIterator first, InputIterator last) + { + T *pointer=_pointer.getPointer(); + while(first!=last) + { + if(_nb_of_elem>=_nb_of_elem_alloc || _nb_of_elem==0) + { + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + pointer=_pointer.getPointer(); + } + pointer[_nb_of_elem++]=*first++; + } + } + + template + void MemArray::pushBack(T elem) throw(INTERP_KERNEL::Exception) + { + if(_nb_of_elem>=_nb_of_elem_alloc) + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + T *pt=getPointer(); + pt[_nb_of_elem++]=elem; + } + + template + T MemArray::popBack() throw(INTERP_KERNEL::Exception) + { + if(_nb_of_elem>0) + { + const T *pt=getConstPointer(); + return pt[--_nb_of_elem]; + } + throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !"); + } + + template + void MemArray::pack() const + { + if(_nb_of_elem>=0) + (const_cast * >(this))->reserve(_nb_of_elem); } template @@ -110,7 +159,7 @@ namespace ParaMEDMEM } if(pt1==pt2) return true; - for(int i=0;i<_nb_of_elem;i++) + for(std::size_t i=0;i<_nb_of_elem;i++) if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec) { oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i]; @@ -119,32 +168,45 @@ namespace ParaMEDMEM } return true; } - + /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components + * \return True if a not null pointer is present, False if not. */ template - void MemArray::repr(int sl, std::ostream& stream) const + bool MemArray::reprHeader(int sl, std::ostream& stream) const { stream << "Number of tuples : "; if(!_pointer.isNull()) { if(sl!=0) - stream << _nb_of_elem/sl; - else + stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc; + else stream << "Empty Data"; } else stream << "No data"; stream << "\n"; stream << "Data content :\n"; - const T *data=getConstPointer(); - if(!_pointer.isNull()) + bool ret=!_pointer.isNull(); + if(!ret) + stream << "No data !\n"; + return ret; + } + + /*! + * \param [in] sl is typically the number of components + */ + template + void MemArray::repr(int sl, std::ostream& stream) const + { + if(reprHeader(sl,stream)) { + const T *data=getConstPointer(); if(_nb_of_elem!=0 && sl!=0) { - int nbOfTuples=_nb_of_elem/sl; - for(int i=0;i(stream," ")); @@ -155,12 +217,10 @@ namespace ParaMEDMEM else stream << "Empty Data\n"; } - else - stream << "No data !\n"; } /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components */ template void MemArray::reprZip(int sl, std::ostream& stream) const @@ -182,8 +242,8 @@ namespace ParaMEDMEM { if(_nb_of_elem!=0 && sl!=0) { - int nbOfTuples=_nb_of_elem/sl; - for(int i=0;i(stream," ")); @@ -209,11 +269,13 @@ namespace ParaMEDMEM template T *MemArray::fromNoInterlace(int nbOfComp) const { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::fromNoInterlace : number of components must be > 0 !"); const T *pt=_pointer.getConstPointer(); - int nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=new T[_nb_of_elem]; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); T *w=ret; - for(int i=0;i T *MemArray::toNoInterlace(int nbOfComp) const { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::toNoInterlace : number of components must be > 0 !"); const T *pt=_pointer.getConstPointer(); - int nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=new T[_nb_of_elem]; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); T *w=ret; for(int i=0;i - void MemArray::reverse() + void MemArray::reverse(int nbOfComp) { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::reverse : only supported with 'this' array with ONE or more than ONE component !"); T *pt=_pointer.getPointer(); - std::reverse(pt,pt+_nb_of_elem); + if(nbOfComp==1) + { + std::reverse(pt,pt+_nb_of_elem); + return ; + } + else + { + T *pt2=pt+_nb_of_elem-nbOfComp; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + for(std::size_t i=0;i - void MemArray::alloc(int nbOfElements) throw(INTERP_KERNEL::Exception) + void MemArray::alloc(std::size_t nbOfElements) throw(INTERP_KERNEL::Exception) { destroy(); if(nbOfElements<0) throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !"); _nb_of_elem=nbOfElements; - _pointer.setInternal(new T[_nb_of_elem]); + _nb_of_elem_alloc=nbOfElements; + _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T))); _ownership=true; - _dealloc=CPP_DEALLOC; + _dealloc=CDeallocator; } - + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray::reAlloc method. + * So after the call of this method \a _nb_of_elem will be equal tostd::min(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to + * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation. + * So after the call of this method the accessible content is perfectly set. + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ + template + void MemArray::reserve(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception) + { + if(newNbOfElements<0) + throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !"); + if(_nb_of_elem_alloc==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); + if(_ownership) + destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external + _pointer.setInternal(pointer); + _nb_of_elem=std::min(_nb_of_elem,newNbOfElements); + _nb_of_elem_alloc=newNbOfElements; + _ownership=true; + _dealloc=CDeallocator; + _param_for_deallocator=0; + } + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min(_nb_of_elem,newNbOfElements) come from the . + * The remaing part of the new allocated chunk are available but not set previouly ! + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ template - void MemArray::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception) + void MemArray::reAlloc(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception) { if(newNbOfElements<0) throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !"); - T *pointer=new T[newNbOfElements]; - std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); + if(_nb_of_elem==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); if(_ownership) - destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external + destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external _pointer.setInternal(pointer); _nb_of_elem=newNbOfElements; + _nb_of_elem_alloc=newNbOfElements; _ownership=true; - _dealloc=CPP_DEALLOC; + _dealloc=CDeallocator; + _param_for_deallocator=0; + } + + template + void MemArray::CPPDeallocator(void *pt, void *param) + { + delete [] reinterpret_cast(pt); + } + + template + void MemArray::CDeallocator(void *pt, void *param) + { + free(pt); } template - void MemArray::destroyPointer(T *pt, DeallocType type) + typename MemArray::Deallocator MemArray::BuildFromType(DeallocType type) throw(INTERP_KERNEL::Exception) { switch(type) { case CPP_DEALLOC: - { - delete [] pt; - return ; - } + return CPPDeallocator; case C_DEALLOC: - { - free(pt); - return ; - } + return CDeallocator; default: - std::ostringstream stream; - stream << "Invalid deallocation requested for pointer " << pt; - throw INTERP_KERNEL::Exception(stream.str().c_str()); + throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !"); } } + template + void MemArray::destroyPointer(T *pt, typename MemArray::Deallocator dealloc, void *param) + { + if(dealloc) + dealloc(pt,param); + } + template void MemArray::destroy() { if(_ownership) - destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external + destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external _pointer.null(); _ownership=false; + _dealloc=NULL; + _param_for_deallocator=NULL; } template diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx new file mode 100644 index 000000000..ea09de283 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -0,0 +1,2515 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "MEDCouplingMemArray.txx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include +#include +#include +#include +#include +#include + +using namespace ParaMEDMEM; + +/*! + * Checks if raw data is allocated. Read more on the raw data + * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return bool - \a true if the raw data is allocated, \a false else. + */ +bool DataArrayChar::isAllocated() const throw(INTERP_KERNEL::Exception) +{ + return getConstPointer()!=0; +} + +/*! + * Checks if raw data is allocated and throws an exception if it is not the case. + * \throw If the raw data is not allocated. + */ +void DataArrayChar::checkAllocated() const throw(INTERP_KERNEL::Exception) +{ + if(!isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); +} + +std::size_t DataArrayChar::getHeapMemorySize() const +{ + std::size_t sz=_mem.getNbOfElemAllocated(); + return DataArray::getHeapMemorySize()+sz; +} + +/*! + * Returns an integer value characterizing \a this array, which is useful for a quick + * comparison of many instances of DataArrayInt. + * \return int - the hash value. + * \throw If \a this is not allocated. + */ +int DataArrayChar::getHashCode() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + std::size_t nbOfElems=getNbOfElems(); + int ret=nbOfElems*65536; + int delta=3; + if(nbOfElems>48) + delta=nbOfElems/8; + int ret0=0; + const char *pt=begin(); + for(std::size_t i=0;igetNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ +void DataArrayChar::reverse() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); +} + +/*! + * Assign zero to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \throw If \a this is not allocated. + */ +void DataArrayChar::fillWithZero() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.fillWithValue(0); + declareAsNew(); +} + +/*! + * Assign \a val to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \param [in] val - the value to fill with. + * \throw If \a this is not allocated. + */ +void DataArrayChar::fillWithValue(char val) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.fillWithValue(val); + declareAsNew(); +} + +/*! + * Returns a textual and human readable representation of \a this instance of + * DataArrayChar. This text is shown when a DataArrayChar is printed in Python. + * \return std::string - text describing \a this DataArrayChar. + */ +std::string DataArrayChar::repr() const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayChar::reprZip() const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream ret; + reprZipStream(ret); + return ret.str(); +} + +/*! + * Changes number of tuples in the array. If the new number of tuples is smaller + * than the current number the array is truncated, otherwise the array is extended. + * \param [in] nbOfTuples - new number of tuples. + * \throw If \a this is not allocated. + */ +void DataArrayChar::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); + declareAsNew(); +} + +/*! + * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this + * array to the new one. + * \return DataArrayInt * - the new instance of DataArrayChar. + */ +DataArrayInt *DataArrayChar::convertToIntArr() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(getNumberOfTuples(),getNumberOfComponents()); + std::size_t nbOfVals=getNbOfElems(); + const char *src=getConstPointer(); + int *dest=ret->getPointer(); + std::copy(src,src+nbOfVals,dest); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * Permutes values of \a this array as required by \a old2New array. The values are + * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains + * the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + */ +void DataArrayChar::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + char *tmp=new char[nbTuples*nbOfCompo]; + const char *iptr=getConstPointer(); + for(int i=0;igetNumberOfTuples() + * giving a previous position of i-th new value. + */ +void DataArrayChar::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + char *tmp=new char[nbTuples*nbOfCompo]; + const char *iptr=getConstPointer(); + for(int i=0;igetNumberOfTuples() + * giving a new position for i-th old value. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ +DataArrayChar *DataArrayChar::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Returns a copy of \a this array with values permuted as required by \a new2Old array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of + * tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + */ +DataArrayChar *DataArrayChar::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is + * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all + * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which + * \a old2New[ i ] is negative, is missing from the result array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old tuple and giving negative position for + * for i-th old tuple that should be omitted. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + */ +DataArrayChar *DataArrayChar::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(newNbOfTuple,nbOfCompo); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;i=0) + std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * This method is equivalent to selectByTupleId() except that it prevents coping data + * from behind the end of \a this array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). + */ +DataArrayChar *DataArrayChar::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + int nbComp=getNumberOfComponents(); + int oldNbOfTuples=getNumberOfTuples(); + ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + char *pt=ret->getPointer(); + const char *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + if(*w>=0 && *wgetNumberOfTuples) !"); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Returns a shorten copy of \a this array. The new DataArrayChar contains every + * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th + * tuple. Indices of the selected tuples are the same as ones returned by the Python + * command \c range( \a bg, \a end2, \a step ). + * This method is equivalent to selectByTupleIdSafe() except that the input array is + * not constructed explicitly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] bg - index of the first tuple to copy from \a this array. + * \param [in] end2 - index of the tuple before which the tuples to copy are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If (\a end2 < \a bg) or (\a step <= 0). + * \sa DataArrayChar::substr. + */ +DataArrayChar *DataArrayChar::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + int nbComp=getNumberOfComponents(); + int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); + ret->alloc(newNbOfTuples,nbComp); + char *pt=ret->getPointer(); + const char *srcPt=getConstPointer()+bg*nbComp; + for(int i=0;icopyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * Checks if all values in \a this array are equal to \a val. + * \param [in] val - value to check equality of array values to. + * \return bool - \a true if all values are \a val. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1 + */ +bool DataArrayChar::isUniform(char val) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !"); + int nbOfTuples=getNumberOfTuples(); + const char *w=getConstPointer(); + const char *end2=w+nbOfTuples; + for(;w!=end2;w++) + if(*w!=val) + return false; + return true; +} + +/*! + * Changes the number of components within \a this array so that its raw data **does + * not** change, instead splitting this data into tuples changes. + * \param [in] newNbOfComp - number of components for \a this array to have. + * \throw If \a this is not allocated + * \throw If getNbOfElems() % \a newNbOfCompo != 0. + * \throw If \a newNbOfCompo is lower than 1. + * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). + * \warning This method erases all (name and unit) component info set before! + */ +void DataArrayChar::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(newNbOfCompo<1) + throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : input newNbOfCompo must be > 0 !"); + std::size_t nbOfElems=getNbOfElems(); + if(nbOfElems%newNbOfCompo!=0) + throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : nbOfElems%newNbOfCompo!=0 !"); + if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) + throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); + _info_on_compo.clear(); + _info_on_compo.resize(newNbOfCompo); + declareAsNew(); +} + +/*! + * Returns a shorten copy of \a this array. The new DataArrayChar contains all + * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before + * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). + * This method is a specialization of selectByTupleId2(). + * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. + * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. + * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a tupleIdBg < 0. + * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). + \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). + * \sa DataArrayChar::selectByTupleId2 + */ +DataArrayChar *DataArrayChar::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbt=getNumberOfTuples(); + if(tupleIdBg<0) + throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter must be greater than 0 !"); + if(tupleIdBg>nbt) + throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater than number of tuples !"); + int trueEnd=tupleIdEnd; + if(tupleIdEnd!=-1) + { + if(tupleIdEnd>nbt) + throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + } + else + trueEnd=nbt; + int nbComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(trueEnd-tupleIdBg,nbComp); + ret->copyStringInfoFrom(*this); + std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); + return ret.retn(); +} + +/*! + * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then the result array is shorten as each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is + * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp + * components. + * \param [in] newNbOfComp - number of components for the new array to have. + * \param [in] dftValue - value assigned to new values added to the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + */ +DataArrayChar *DataArrayChar::changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(getNumberOfTuples(),newNbOfComp); + const char *oldc=getConstPointer(); + char *nc=ret->getPointer(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + int dim=std::min(oldNbOfComp,newNbOfComp); + for(int i=0;isetName(getName().c_str()); + for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); + ret->setName(getName().c_str()); + return ret.retn(); +} + +/*! + * Returns a copy of \a this array composed of selected components. + * The new DataArrayChar has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result array + * can be either less, same or more than \a this->getNbOfElems(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new array. + * \return DataArrayChar * - the new instance of DataArrayChar that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + * + * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + */ +DataArray *DataArrayChar::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr ret(buildEmptySpecializedDAChar()); + int newNbOfCompo=(int)compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) + DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component"); + int nbOfTuples=getNumberOfTuples(); + ret->alloc(nbOfTuples,newNbOfCompo); + ret->copyPartOfStringInfoFrom(*this,compoIds); + const char *oldc=getConstPointer(); + char *nc=ret->getPointer(); + for(int i=0;icheckAllocated(); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples!=other->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !"); + int nbOfComp1=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char)); + char *w=newArr; + const char *inp1=getConstPointer(); + const char *inp2=other->getConstPointer(); + for(int i=0;i compIds(nbOfComp2); + for(int i=0;igetNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". + */ +void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues1 : DataArrayChar pointer in input is NULL !"); + const char msg[]="DataArrayChar::setPartOfValues1"; + checkAllocated(); + a->checkAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); + DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + char *pt=getPointer()+bgTuples*nbComp+bgComp; + const char *srcPt=a->getConstPointer(); + if(assignTech) + { + for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign values of \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - this parameter is checked only if the + * *mode of usage* is the first; if it is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() != (endComp - bgComp) . + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() != (endComp - bgComp). + * + * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". + */ +void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues2 : DataArrayChar pointer in input is NULL !"); + const char msg[]="DataArrayChar::setPartOfValues2"; + checkAllocated(); + a->checkAllocated(); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + int newNbOfTuples=(int)std::distance(bgTuples,endTuples); + int newNbOfComp=(int)std::distance(bgComp,endComp); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + char *pt=getPointer(); + const char *srcPt=a->getConstPointer(); + if(assignTech) + { + for(const int *w=bgTuples;w!=endTuples;w++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + for(const int *z=bgComp;z!=endComp;z++,srcPt++) + { + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; + } + } + } + else + { + for(const int *w=bgTuples;w!=endTuples;w++) + { + const char *srcPt2=srcPt; + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + for(const int *z=bgComp;z!=endComp;z++,srcPt2++) + { + pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; + } + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples and components to assign to are defined by C arrays of indices. + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (\a pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * + * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". + */ +void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + char *pt=getPointer(); + for(const int *w=bgTuples;w!=endTuples;w++) + for(const int *z=bgComp;z!=endComp;z++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+(*z)]=a; + } +} + +/*! + * Copy all values from another DataArrayChar (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - this parameter is checked only in the first + * *mode of usage*; if \a strictCompoCompare is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". + */ +void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues3 : DataArrayChar pointer in input is NULL !"); + const char msg[]="DataArrayChar::setPartOfValues3"; + checkAllocated(); + a->checkAllocated(); + int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); + int newNbOfTuples=(int)std::distance(bgTuples,endTuples); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + char *pt=getPointer()+bgComp; + const char *srcPt=a->getConstPointer(); + if(assignTech) + { + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;j(pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". + */ +void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="DataArrayChar::setPartOfValuesSimple3"; + checkAllocated(); + int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); + char *pt=getPointer()+bgComp; + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;jcheckAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + int newNbOfComp=(int)std::distance(bgComp,endComp); + int nbComp=getNumberOfComponents(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); + bool assignTech=true; + if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) + { + if(strictCompoCompare) + a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); + } + else + { + a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); + assignTech=false; + } + const char *srcPt=a->getConstPointer(); + char *pt=getPointer()+bgTuples*nbComp; + if(assignTech) + { + for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 2. + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * the corresponding (\a this or \a a) array. + */ +void DataArrayChar::setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) throw(INTERP_KERNEL::Exception) +{ + if(!a || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : DataArrayChar pointer in input is NULL !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayChar instance with exactly 2 components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + char *valsToSet=getPointer(); + const char *valsSrc=a->getConstPointer(); + for(const char *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) + { + if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; + oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; + oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Copy some tuples from another DataArrayChar (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by \a tuplesSelec->getNumberOfTuples(). + * The tuples to copy are defined by values of a DataArrayChar. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a a array. + */ +void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) +{ + if(!aBase || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayChar *a=dynamic_cast(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayChar !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayChar instance with exactly 1 component !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); + char *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : invalid number range of values to write !"); + const char *valsSrc=a->getConstPointer(); + for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) + { + if(*tuple>=0 && *tuplebegin(),tuple); + oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Copy some tuples from another DataArrayChar (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to copy are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by number of tuples to copy. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a a. + * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). + * \throw If parameters specifying tuples to copy, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for the array \a a. + */ +void DataArrayChar::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayChar *a=dynamic_cast(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayChar !"); + checkAllocated(); + a->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + const char msg[]="DataArrayChar::setContigPartOfSelectedValues2"; + int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + char *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid number range of values to write !"); + if(end2>aNt) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : invalid range of values to read !"); + const char *valsSrc=a->getConstPointer()+bg*nbOfComp; + for(int i=0;i \a this->getNumberOfTuples(). + * \throw If \a this is not allocated. + */ +DataArray *DataArrayChar::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuplesThis=getNumberOfTuples(); + if(ranges.empty()) + { + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(0,nbOfComp); + ret->copyStringInfoFrom(*this); + return ret.retn(); + } + int ref=ranges.front().first; + int nbOfTuples=0; + bool isIncreasing=true; + for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) + { + if((*it).first<=(*it).second) + { + if((*it).first>=0 && (*it).second<=nbOfTuplesThis) + { + nbOfTuples+=(*it).second-(*it).first; + if(isIncreasing) + isIncreasing=ref<=(*it).first; + ref=(*it).second; + } + else + { + std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); + oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); + oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(isIncreasing && nbOfTuplesThis==nbOfTuples) + return deepCpy(); + MEDCouplingAutoRefCountObjectPtr ret=buildEmptySpecializedDAChar(); + ret->alloc(nbOfTuples,nbOfComp); + ret->copyStringInfoFrom(*this); + const char *src=getConstPointer(); + char *work=ret->getPointer(); + for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) + work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); + return ret.retn(); +} + +/*! + * Returns a value located at specified tuple and component. + * This method is equivalent to DataArrayChar::getIJ() except that validity of + * parameters is checked. So this method is safe but expensive if used to go through + * all values of \a this. + * \param [in] tupleId - index of tuple of interest. + * \param [in] compoId - index of component of interest. + * \return double - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. + * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. + */ +char DataArrayChar::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(tupleId<0 || tupleId>=getNumberOfTuples()) + { + std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(compoId<0 || compoId>=getNumberOfComponents()) + { + std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return _mem[tupleId*_info_on_compo.size()+compoId]; +} + +/*! + * Returns the last value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +char DataArrayChar::back() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::back : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayChar::back : number of tuples must be >= 1 !"); + return *(getConstPointer()+nbOfTuples-1); +} + +/*! + * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a + * given one. + * \param [in] val - the value to find within \a this. + * \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ +DataArrayInt *DataArrayChar::getIdsEqual(char val) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); + const char *cptr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;ipushBackSilent(i); + return ret.retn(); +} + +/*! + * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not + * equal to a given one. + * \param [in] val - the value to ignore within \a this. + * \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ +DataArrayInt *DataArrayChar::getIdsNotEqual(char val) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); + const char *cptr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;ipushBackSilent(i); + return ret.retn(); +} + +/*! + * This method searches the sequence specified in input parameter \b vals in \b this. + * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). + * This method differs from DataArrayChar::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::locateTuple. + * \sa DataArrayChar::locateTuple + */ +int DataArrayChar::search(const std::vector& vals) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if(nbOfCompo!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::search : works only for DataArrayChar instance with one component !"); + const char *cptr=getConstPointer(); + std::size_t nbOfVals=getNbOfElems(); + const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end()); + if(loc!=cptr+nbOfVals) + return std::distance(cptr,loc); + return -1; +} + +/*! + * This method is an extension of DataArrayChar::locateValue method because this method works for DataArrayChar with + * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). + * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. + * If any the tuple id is returned. If not -1 is returned. + * + * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of + * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. + * + * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this. + * \sa DataArrayChar::search. + */ +int DataArrayChar::locateTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if(nbOfCompo==0) + throw INTERP_KERNEL::Exception("DataArrayChar::locateTuple : 0 components in 'this' !"); + if(nbOfCompo!=(int)tupl.size()) + { + std::ostringstream oss; oss << "DataArrayChar::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const char *cptr=getConstPointer(); + std::size_t nbOfVals=getNbOfElems(); + for(const char *work=cptr;work!=cptr+nbOfVals;) + { + work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end()); + if(work!=cptr+nbOfVals) + { + if(std::distance(cptr,work)%nbOfCompo!=0) + work++; + else + return std::distance(cptr,work)/nbOfCompo; + } + } + return -1; +} + +/*! + * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with + * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). + * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. + * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of + * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. + * \sa DataArrayChar::locateTuple + */ +bool DataArrayChar::presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception) +{ + return locateTuple(tupl)!=-1; +} + +/*! + * Returns \a true if a given value is present within \a this one-dimensional array. + * \param [in] value - the value to find within \a this array. + * \return bool - \a true in case if \a value is present within \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa locateValue() + */ +bool DataArrayChar::presenceOfValue(char value) const throw(INTERP_KERNEL::Exception) +{ + return locateValue(value)!=-1; +} + +/*! + * This method expects to be called when number of components of this is equal to one. + * This method returns true if it exists a tuple so that the value is contained in \b vals. + * If not any tuple contains one of the values contained in 'vals' false is returned. + * \sa DataArrayChar::locateValue + */ +bool DataArrayChar::presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception) +{ + return locateValue(vals)!=-1; +} + +/*! + * This method expects to be called when number of components of this is equal to one. + * This method returns the tuple id, if it exists, of the first tuple equal to \b value. + * If not any tuple contains \b value -1 is returned. + * \sa DataArrayChar::presenceOfValue + */ +int DataArrayChar::locateValue(char value) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); + const char *cptr=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + const char *ret=std::find(cptr,cptr+nbOfTuples,value); + if(ret!=cptr+nbOfTuples) + return std::distance(cptr,ret); + return -1; +} + +/*! + * This method expects to be called when number of components of this is equal to one. + * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals. + * If not any tuple contains one of the values contained in 'vals' false is returned. + * \sa DataArrayChar::presenceOfValue + */ +int DataArrayChar::locateValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !"); + std::set vals2(vals.begin(),vals.end()); + const char *cptr=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + for(const char *w=cptr;w!=cptr+nbOfTuples;w++) + if(vals2.find(*w)!=vals2.end()) + return std::distance(cptr,w); + return -1; +} + +/*! + * Returns the maximal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the maximal value. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ +char DataArrayChar::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !"); + const char *vals=getConstPointer(); + const char *loc=std::max_element(vals,vals+nbOfTuples); + tupleId=(int)std::distance(vals,loc); + return *loc; +} + +/*! + * Returns the maximal value within \a this array that is allowed to have more than + * one component. + * \return char - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +char DataArrayChar::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const char *loc=std::max_element(begin(),end()); + return *loc; +} + +/*! + * Returns the minimal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the minimal value. + * \return char - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ +char DataArrayChar::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !"); + const char *vals=getConstPointer(); + const char *loc=std::min_element(vals,vals+nbOfTuples); + tupleId=(int)std::distance(vals,loc); + return *loc; +} + +/*! + * Returns the minimal value within \a this array that is allowed to have more than + * one component. + * \return char - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +char DataArrayChar::getMinValueInArray() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + const char *loc=std::min_element(begin(),end()); + return *loc; +} + +/*! + * This method works only on data array with one component. + * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that + * this[*id] in [\b vmin,\b vmax) + * + * \param [in] vmin begin of range. This value is included in range. + * \param [out] vmax end of range. This value is \b not included in range. + * \return a newly allocated data array that the caller should deal with. + */ +DataArrayInt *DataArrayChar::getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getIdsInRange : this must have exactly one component !"); + const char *cptr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i=vmin && *cptrpushBackSilent(i); + return ret.retn(); +} + +/*! + * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number + * of tuples in the result array is a1->getNumberOfTuples() + a2->getNumberOfTuples() - + * offsetA2 and (2) + * the number of component in the result array is same as that of each of given arrays. + * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \param [in] offsetA2 - number of tuples of \a a2 to skip. + * \return DataArrayChar * - the new instance of DataArrayChar. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). + */ +DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !"); + std::vector v(2); v[0]=a1; v[1]=a2; + return Aggregate(v); +} + +/*! + * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayChar * - the new instance of DataArrayChar. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If getNumberOfComponents() of arrays within \a arr. + */ +DataArrayChar *DataArrayChar::Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception) +{ + std::vector a; + for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !"); + std::vector::const_iterator it=a.begin(); + int nbOfComp=(*it)->getNumberOfComponents(); + int nbt=(*it++)->getNumberOfTuples(); + for(int i=1;it!=a.end();it++,i++) + { + if((*it)->getNumberOfComponents()!=nbOfComp) + throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !"); + nbt+=(*it)->getNumberOfTuples(); + } + MEDCouplingAutoRefCountObjectPtr ret=a[0]->buildEmptySpecializedDAChar(); + ret->alloc(nbt,nbOfComp); + char *pt=ret->getPointer(); + for(it=a.begin();it!=a.end();it++) + pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt); + ret->copyStringInfoFrom(*(a[0])); + return ret.retn(); +} + +/*! + * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayChar * - the new instance of DataArrayChar. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If any given array is not allocated. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + */ +DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception) +{ + std::vector arr(2); + arr[0]=a1; arr[1]=a2; + return Meld(arr); +} + +/*! + * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayChar * - the new instance of DataArrayChar. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If any given array is not allocated. + * \throw If getNumberOfTuples() of arrays within \a arr is different. + */ +DataArrayChar *DataArrayChar::Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception) +{ + std::vector a; + for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !"); + std::vector::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector nbc(a.size()); + std::vector pts(a.size()); + nbc[0]=(*it)->getNumberOfComponents(); + pts[0]=(*it++)->getConstPointer(); + for(int i=1;it!=a.end();it++,i++) + { + if(nbOfTuples!=(*it)->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !"); + nbc[i]=(*it)->getNumberOfComponents(); + pts[i]=(*it)->getConstPointer(); + } + int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); + DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar(); + ret->alloc(nbOfTuples,totalNbOfComp); + char *retPtr=ret->getPointer(); + for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str()); + return ret; +} + +/*! + * Sets a C array to be used as raw data of \a this. The previously set info + * of components is retained and re-sized. + * For more info see \ref MEDCouplingArraySteps1. + * \param [in] array - the C array to be used as raw data of \a this. + * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. + * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, + * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, + * \c free(\c array ) will be called. + * \param [in] nbOfTuple - new number of tuples in \a this. + * \param [in] nbOfCompo - new number of components in \a this. + */ +void DataArrayChar::useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) +{ + _info_on_compo.resize(nbOfCompo); + _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); + declareAsNew(); +} + +void DataArrayChar::useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) +{ + _info_on_compo.resize(nbOfCompo); + _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo); + declareAsNew(); +} + +/*! + * Returns a new instance of DataArrayByte. The caller is to delete this array + * using decrRef() as it is no more needed. + */ +DataArrayByte *DataArrayByte::New() +{ + return new DataArrayByte; +} + +DataArrayByteIterator *DataArrayByte::iterator() +{ + return new DataArrayByteIterator(this); +} + +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayByte * - a new instance of DataArrayByte. + */ +DataArrayByte *DataArrayByte::deepCpy() const +{ + return new DataArrayByte(*this); +} + +/*! + * Returns either a \a deep or \a shallow copy of this array. For more info see + * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. + * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. + * \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ +DataArrayByte *DataArrayByte::performCpy(bool dCpy) const +{ + if(dCpy) + return deepCpy(); + else + { + incrRef(); + return const_cast(this); + } +} + +/*! + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. + */ +char DataArrayByte::byteValue() const throw(INTERP_KERNEL::Exception) +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !"); +} + +DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception) +{ + return DataArrayByte::New(); +} + +void DataArrayByte::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Name of byte array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayByte::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Name of byte array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + DataArray::reprWithoutNameStream(stream); + if(_mem.reprHeader(getNumberOfComponents(),stream)) + { + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbCompo=getNumberOfComponents(); + for(int i=0;i(stream," "));//it is not a bug int here not char because it is not ASCII here contrary to DataArrayAsciiChar + stream << "\n"; + } + } +} + +void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + DataArray::reprWithoutNameStream(stream); + _mem.reprZip(getNumberOfComponents(),stream); +} + +void DataArrayByte::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); + const char *data=getConstPointer(); + stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl; + if(nbTuples*nbComp>=1) + { + stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={"; + std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); + stream << data[nbTuples*nbComp-1] << "};" << std::endl; + stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; + } + else + stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; + stream << varName << "->setName(\"" << getName() << "\");" << std::endl; +} + +/*! + * Method that gives a quick overvien of \a this for python. + */ +void DataArrayByte::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; + stream << "DataArrayByte C++ instance at " << this << ". "; + if(isAllocated()) + { + int nbOfCompo=(int)_info_on_compo.size(); + if(nbOfCompo>=1) + { + int nbOfTuples=getNumberOfTuples(); + stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; + reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); + } + else + stream << "Number of components : 0."; + } + else + stream << "*** No data allocated ****"; +} + +void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception) +{ + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbOfCompo=(int)_info_on_compo.size(); + std::ostringstream oss2; oss2 << "["; + std::string oss2Str(oss2.str()); + bool isFinished=true; + for(int i=0;i1) + { + oss2 << "("; + for(int j=0;j(&other); + if(!otherC) + { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; } + return DataArrayChar::isEqualIfNotWhy(other,reason); +} + +DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0) +{ + if(_da) + { + _da->incrRef(); + if(_da->isAllocated()) + { + _nb_comp=da->getNumberOfComponents(); + _nb_tuple=da->getNumberOfTuples(); + _pt=da->getPointer(); + } + } +} + +DataArrayByteIterator::~DataArrayByteIterator() +{ + if(_da) + _da->decrRef(); +} + +DataArrayByteTuple *DataArrayByteIterator::nextt() throw(INTERP_KERNEL::Exception) +{ + if(_tuple_id<_nb_tuple) + { + _tuple_id++; + DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; + } + else + return 0; +} + +DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) +{ +} + +std::string DataArrayByteTuple::repr() const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream oss; oss << "("; + for(int i=0;i<_nb_of_compo-1;i++) + oss << (int)_pt[i] << ", "; + oss << _pt[_nb_of_compo-1] << ")"; + return oss.str(); +} + +char DataArrayByteTuple::byteValue() const throw(INTERP_KERNEL::Exception) +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !"); +} + +/*! + * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayByte::decrRef. + * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayByte::useArray with ownership set to \b false. + * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or + * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. + */ +DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception) +{ + if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) + { + DataArrayByte *ret=DataArrayByte::New(); + ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); + return ret; + } + else + { + std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; + oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array + * using decrRef() as it is no more needed. + */ +DataArrayAsciiChar *DataArrayAsciiChar::New() +{ + return new DataArrayAsciiChar; +} + +/*! + * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array + * using decrRef() as it is no more needed. + * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown. + */ +DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st) throw(INTERP_KERNEL::Exception) +{ + return new DataArrayAsciiChar(st); +} + +/*! + * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown. + */ +DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st) throw(INTERP_KERNEL::Exception) +{ + std::size_t lgth=st.length(); + if(lgth==0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !"); + alloc(1,lgth); + std::copy(st.begin(),st.begin()+lgth,getPointer()); +} + +/*! + * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array + * using decrRef() as it is no more needed. + * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in + * \a vst the remaining locations in memory will be set to character \a defaultChar. + * + * \param [in] defaultChar the default character used to fill not defined locations in \a this + * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained + * in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown. + * + * \throw If input \a vst is empty. + * \throw If all strings in \a vst are empty. + */ +DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector& vst, char defaultChar) throw(INTERP_KERNEL::Exception) +{ + return new DataArrayAsciiChar(vst,defaultChar); +} + +/*! + * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in + * \a vst the remaining locations in memory will be set to character \a defaultChar. + * + * \param [in] defaultChar the default character used to fill not defined locations in \a this + * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained + * in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown. + * + * \throw If input \a vst is empty. + * \throw If all strings in \a vst are empty. + */ +DataArrayAsciiChar::DataArrayAsciiChar(const std::vector& vst, char defaultChar) throw(INTERP_KERNEL::Exception) +{ + if(vst.empty()) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !"); + std::size_t nbCompo=0; + for(std::vector::const_iterator it=vst.begin();it!=vst.end();it++) + nbCompo=std::max(nbCompo,(*it).length()); + if(nbCompo==0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !"); + int nbTuples=(int)vst.size(); + alloc(nbTuples,(int)nbCompo); + char *pt=getPointer(); + for(int i=0;i(this); + } +} + +/*! + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. + */ +char DataArrayAsciiChar::asciiCharValue() const throw(INTERP_KERNEL::Exception) +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !"); +} + +DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception) +{ + return DataArrayAsciiChar::New(); +} + +void DataArrayAsciiChar::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Name of ASCII char array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + stream << "Name of ASCII char array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + DataArray::reprWithoutNameStream(stream); + if(_mem.reprHeader(getNumberOfComponents(),stream)) + { + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbCompo=getNumberOfComponents(); + for(int i=0;i(stream)); + stream << "\"\n"; + } + } +} + +void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + reprWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); + const char *data=getConstPointer(); + stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl; + if(nbTuples*nbComp>=1) + { + stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={"; + std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator(stream,",")); + stream << data[nbTuples*nbComp-1] << "};" << std::endl; + stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl; + } + else + stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl; + stream << varName << "->setName(\"" << getName() << "\");" << std::endl; +} + +/*! + * Method that gives a quick overvien of \a this for python. + */ +void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) +{ + static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300; + stream << "DataArrayAsciiChar C++ instance at " << this << ". "; + if(isAllocated()) + { + int nbOfCompo=(int)_info_on_compo.size(); + if(nbOfCompo>=1) + { + int nbOfTuples=getNumberOfTuples(); + stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl; + reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR); + } + else + stream << "Number of components : 0."; + } + else + stream << "*** No data allocated ****"; +} + +void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception) +{ + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbOfCompo=(int)_info_on_compo.size(); + std::ostringstream oss2; oss2 << "["; + std::string oss2Str(oss2.str()); + bool isFinished=true; + for(int i=0;i(&other); + if(!otherC) + { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; } + return DataArrayChar::isEqualIfNotWhy(other,reason); +} + +DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0) +{ + if(_da) + { + _da->incrRef(); + if(_da->isAllocated()) + { + _nb_comp=da->getNumberOfComponents(); + _nb_tuple=da->getNumberOfTuples(); + _pt=da->getPointer(); + } + } +} + +DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator() +{ + if(_da) + _da->decrRef(); +} + +DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt() throw(INTERP_KERNEL::Exception) +{ + if(_tuple_id<_nb_tuple) + { + _tuple_id++; + DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; + } + else + return 0; +} + +DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) +{ +} + +std::string DataArrayAsciiCharTuple::repr() const throw(INTERP_KERNEL::Exception) +{ + std::ostringstream oss; + std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator(oss)); + return oss.str(); +} + +char DataArrayAsciiCharTuple::asciiCharValue() const throw(INTERP_KERNEL::Exception) +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !"); +} + +/*! + * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayAsciiChar::decrRef. + * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayAsciiChar::useArray with ownership set to \b false. + * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or + * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. + */ +DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception) +{ + if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) + { + DataArrayAsciiChar *ret=DataArrayAsciiChar::New(); + ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); + return ret; + } + else + { + std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo; + oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index e0a9c7883..95d450a9c 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -43,6 +43,11 @@ MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name { } +std::size_t MEDCouplingMesh::getHeapMemorySize() const +{ + return _name.capacity()+_description.capacity()+_time_unit.capacity(); +} + /*! * This method is only for ParaMEDMEM in ParaFIELD constructor. */ @@ -95,6 +100,12 @@ bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, return true; } +/*! + * Checks if \a this and another MEDCouplingMesh are fully equal. + * \param [in] other - an instance of MEDCouplingMesh to compare with \a this one. + * \param [in] prec - precision value used to compare node coordinates. + * \return bool - \c true if the two meshes are equal, \c false else. + */ bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { std::string tmp; @@ -102,21 +113,37 @@ bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const t } /*! - * This method checks geo equivalence between two meshes : 'this' and 'other'. - * If no exception is throw 'this' and 'other' are geometrically equivalent regarding 'levOfCheck' level. - * This method is typically used to change the mesh of a field "safely" depending the 'levOfCheck' level considered. + * This method checks geo equivalence between two meshes : \a this and \a other. + * If no exception is thrown \a this and \a other are geometrically equivalent regarding \a levOfCheck level. + * This method is typically used to change the mesh of a field "safely" depending the \a levOfCheck level considered. * - * @param levOfCheck input that specifies the level of check specified. The possible values are listed below. - * @param prec input that specifies precision for double float data used for comparison in meshes. - * @param cellCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for cells from 'other' to 'this'. - * @param nodeCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for nodes from 'other' to 'this'. + * In case of success cell \c other[i] is equal to the cell \c this[cellCor[i]]. + * In case of success node \c other->getCoords()[i] is equal to the node \c this->getCoords()[nodeCor[i]]. + * + * If \a cellCor is null (or Py_None) it means that for all #i cell in \a other is equal to cell # i in \a this. + * + * If \a nodeCor is null (or Py_None) it means that for all #i node in \a other is equal to node # i in \a this. + * + * So null (or Py_None) returned in \a cellCor and/or \a nodeCor means identity array. This is for optimization reason to avoid to build useless arrays + * for some \a levOfCheck (for example 0). + * + * **Warning a not null output does not mean that it is not identity !** + * + * \param [in] other - the mesh to be compared with \a this. + * \param [in] levOfCheck - input that specifies the level of check specified. The possible values are listed below. + * \param [in] prec - input that specifies precision for double float data used for comparison in meshes. + * \param [out] cellCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for cells from \a other to \a this. + * \param [out] nodeCor - output array not always informed (depending \a levOfCheck param) that gives the corresponding array for nodes from \a other to \a this. * * Possible values for levOfCheck : - * - 0 for strict equality. This is the strongest level. 'cellCor' and 'nodeCor' params are never informed. - * - 10,11,12 for less strict equality. Two meshes are compared geometrically. In case of success 'cellCor' and 'nodeCor' are informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) - * - 20,21,22, for less strict equality. Two meshes are compared geometrically. The difference with the previous version is that nodes(coordinates) are expected to be the same between this and other. In case of success 'cellCor' is informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) + * - 0 for strict equality. This is the strongest level. \a cellCor and \a nodeCor params are never informed. + * - 10,11,12 (10+x) for less strict equality. Two meshes are compared geometrically. In case of success \a cellCor and \a nodeCor are informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) + * - 20,21,22 (20+x), for less strict equality. Two meshes are compared geometrically. The difference with the previous version is that nodes(coordinates) are expected to be the same between this and other. In case of success \a cellCor is informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) * - 1 for fast 'equality'. This is a lazy level. Just number of cells and number of nodes are considered here and 3 cells (begin,middle,end) * - 2 for deep 'equality' as 0 option except that no control is done on all strings in mesh. + * + * So the most strict level of check is 0 (equality). The least strict is 12. If the level of check 12 throws, the 2 meshes \a this and \a other are not similar enough + * to be compared. An interpolation using MEDCouplingRemapper class should be then used. */ void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) @@ -164,9 +191,13 @@ void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levO } /*! - * Given a nodeIds range ['partBg','partEnd'), this method returns the set of cell ids in ascendant order whose connectivity of - * these cells are fully included in the range. As a consequence the returned set of cell ids does \b not \b always fit the nodes in ['partBg','partEnd') - * This method returns the corresponding cells in a newly created array that the caller has the responsability. + * Finds cells whose all nodes are in a given array of node ids. + * \param [in] partBg - the array of node ids. + * \param [in] partEnd - end of \a partBg, i.e. a pointer to a (last+1)-th element + * of \a partBg. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found + * cells. The caller is to delete this array using decrRef() as it is no + * more needed. */ DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const { @@ -191,7 +222,7 @@ DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partB } /*! - * This method checks fastly that 'this' and 'other' are equal. All common checks are done here. + * This method checks fastly that \a this and \a other are equal. All common checks are done here. */ void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { @@ -204,7 +235,7 @@ void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double } /*! - * This method is very poor and looks only if 'this' and 'other' are candidate for merge of fields lying repectively on them. + * This method is very poor and looks only if \a this and \a other are candidate for merge of fields lying repectively on them. */ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const { @@ -216,7 +247,29 @@ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const } /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. + * This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. + * + * \sa MEDCouplingMesh::buildPart + */ +MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildPart(cellIds->begin(),cellIds->end()); +} + +/*! + * This method is equivalent to MEDCouplingMesh::buildPartAndReduceNodes method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds. + * + * \sa MEDCouplingMesh::buildPartAndReduceNodes + */ +MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildPartAndReduceNodes(cellIds->begin(),cellIds->end(),arr); +} + +/*! + * This method builds a field lying on \a this with 'nbOfComp' components. * 'func' is a pointer that points to a function that takes 2 arrays in parameter and returns a boolean. * The first array is a in-param of size this->getSpaceDimension and the second an out param of size 'nbOfComp'. * The return field will have type specified by 't'. 't' is also used to determine where values of field will be @@ -225,18 +278,19 @@ bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const * The 'func' is a callback that takes as first parameter an input array of size 'this->getSpaceDimension()', * the second parameter is a pointer on a valid zone of size at least equal to 'nbOfComp' values. And too finish * the returned value is a boolean that is equal to False in case of invalid evaluation (log(0) for example...) - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func pointer to a function that should return false if the evaluation failed. (division by 0. for example) - * @return field with counter = 1. + * + * \param t type of field returned and specifies where the evaluation of func will be done. + * \param nbOfComp number of components of returned field. + * \param func pointer to a function that should return false if the evaluation failed. (division by 0. for example) + * \return field with counter = 1. */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! @@ -252,7 +306,7 @@ void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(IN /*! * This method copies all attributes that are \b NOT arrays in this. - * All tiny attributes not usefully for state of 'this' are ignored. + * All tiny attributes not usefully for state of \a this are ignored. */ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) { @@ -263,87 +317,166 @@ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTER } /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. - * This method is equivalent to those taking a C++ function pointer except that here the 'func' is informed by - * an interpretable input string. + * \anchor mcmesh_fillFromAnalytic + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. The function can include arbitrary named variables + * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of + * variables are sorted in \b alphabetical \b order to associate a variable name with a + * component. For example, in the expression "2*x+z", "x" stands for the component #0 + * and "z" stands for the component #1 (\b not #2)!
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of the field. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (5.,5.,5.,5.) + * - "2*x + 0*y + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) * - * The dynamic interpretor uses \b alphabetical \b order to assign the component id to the var name. - * For example : - * - "2*x+z" func : x stands for component #0 and z stands for component #1 \b NOT #2 ! - * - * Some var names are reserved and have special meaning. IVec stands for (1,0,0,...). JVec stands for (0,1,0...). - * KVec stands for (0,0,1,...)... These keywords allows too differentate the evaluation of output components each other. - * - * If 'nbOfComp' equals to 4 for example and that 'this->getSpaceDimension()' equals to 3. - * - * For the input tuple T = (1.,3.,7.) : - * - '2*x+z' will return (5.,5.,5.,5.) - * - '2*x+0*y+z' will return (9.,9.,9.,9.) - * - '2*x*IVec+(x+z)*LVec' will return (2.,0.,0.,4.) - * - '2*x*IVec+(y+z)*KVec' will return (2.,0.,10.,0.) + * \param [in] t - the field type. It defines, apart from other things, points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic "Here is a Python example". */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. This method is different than MEDCouplingMesh::fillFromAnalytic, because the info on components are used here to determine vars pos in 'func'. + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters. This method differs from + * \ref MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const "fillFromAnalytic()" + * by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a variable name corresponding to a component is retrieved from + * a corresponding node coordinates array (where it is set via + * DataArrayDouble::setInfoOnComponent()).
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of + * spatial components are "x", "y" and "z", coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \param [in] t - the field type. It defines, apart from other things, the points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the node coordinates are not defined. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. + * + * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic2(nbOfComp,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. This method is different than MEDCouplingMesh::fillFromAnalytic, because 'varsOrder' specifies the pos to assign of vars in 'func'. + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters. This method differs from \ref \ref mcmesh_fillFromAnalytic + * "fillFromAnalytic()" by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a component index of a variable is defined by a + * rank of the variable within the input array \a varsOrder.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. + * In a general case, a value resulting from the function evaluation is assigned to all + * components of the field. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of + * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) + * + * \param [in] t - the field type. It defines, apart from other things, the points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] varsOrder - the vector defining names of variables used to refer to + * components of coordinates of field location points. A variable named + * varsOrder[0] refers to the component #0 etc. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the node coordinates are not defined. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const char *func) const { - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); ret->setMesh(this); ret->fillFromAnalytic3(nbOfComp,varsOrder,func); - ret->incrRef(); - return ret; + ret->synchronizeTimeWithSupport(); + return ret.retn(); } /*! - * retruns a newly created mesh with counter=1 - * that is the union of \b mesh1 and \b mesh2 if possible. The cells of \b mesh2 will appear after cells of \b mesh1. Idem for nodes. - * The only contraint is that \b mesh1 an \b mesh2 have the same mesh types. If it is not the case please use the other API of MEDCouplingMesh::MergeMeshes, - * with input vector of meshes. + * Creates a new MEDCouplingMesh by concatenating two given meshes, if possible. + * Cells and nodes of + * the first mesh precede cells and nodes of the second mesh within the result mesh. + * The meshes must be of the same mesh type, else, an exception is thrown. The method + * MergeMeshes(), accepting a vector of input meshes, has no such a limitation. + * \param [in] mesh1 - the first mesh. + * \param [in] mesh2 - the second mesh. + * \return MEDCouplingMesh * - the result mesh. It is a new instance of + * MEDCouplingMesh. The caller is to delete this mesh using decrRef() as it + * is no more needed. + * \throw If the meshes are of different mesh type. */ MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception) { @@ -355,10 +488,22 @@ MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, cons } /*! - * retruns a newly created mesh with counter=1 - * that is the union of meshes if possible. The cells of \b meshes[1] will appear after cells of \b meshes[0]. Idem for nodes. - * This method performs a systematic conversion to unstructured meshes before performing aggregation contrary to the other ParaMEDMEM::MEDCouplingMesh::MergeMeshes with - * two parameters that work only on the same type of meshes. So here it is possible to mix different type of meshes. + * Creates a new MEDCouplingMesh by concatenating all given meshes, if possible. + * Cells and nodes of + * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. + * This method performs a systematic conversion to unstructured meshes before + * performing aggregation contrary to the other MergeMeshes() + * with two parameters that works only on the same type of meshes. So here it is possible + * to mix different type of meshes. + * \param [in] meshes - a vector of meshes to concatenate. + * \return MEDCouplingMesh * - the result mesh. It is a new instance of + * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it + * is no more needed. + * \throw If \a meshes.size() == 0. + * \throw If \a size[ *i* ] == NULL. + * \throw If the coordinates is not set in none of the meshes. + * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. + * \throw If the \a meshes are of different dimension (getMeshDimension()). */ MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector& meshes) throw(INTERP_KERNEL::Exception) { @@ -380,6 +525,54 @@ MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector + * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + */ void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const { int ret=getCellContainingPoint(pos,eps); elts.push_back(ret); } +/*! + * Finds cells in contact with several balls (i.e. points with precision). + * This method is an extension of getCellContainingPoint() and + * getCellsContainingPoint() for the case of multiple points. + * \param [in] pos - an array of coordinates of points in full interlace mode : + * X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a + * this->getSpaceDimension() * \a nbOfPoints + * \param [in] nbOfPoints - number of points to locate within \a this mesh. + * \param [in] eps - radius of balls (i.e. the precision). + * \param [in,out] elts - vector returning ids of found cells. + * \param [in,out] eltsIndex - an array, of length \a nbOfPoints + 1, + * dividing cell ids in \a elts into groups each referring to one + * point. Its every element (except the last one) is an index pointing to the + * first id of a group of cells. For example cells in contact with the *i*-th + * point are described by following range of indices: + * [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are + * \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ... + * Number of cells in contact with the *i*-th point is + * \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ]. + * + * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
+ * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + */ void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const { eltsIndex.resize(nbOfPoints+1); @@ -431,8 +660,9 @@ void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints } /*! - * This method writes a file in VTK format into file 'fileName'. - * An exception is thrown if the file is not writable. + * Writes \a this mesh into a VTK format file named as specified. + * \param [in] fileName - the name of the file to write in. + * \throw If \a fileName is not a writable file. */ void MEDCouplingMesh::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception) { diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 2febf8c6b..1bfd57f30 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -37,7 +37,8 @@ namespace ParaMEDMEM UNSTRUCTURED = 5, UNSTRUCTURED_DESC = 6, CARTESIAN = 7, - EXTRUDED = 8 + EXTRUDED = 8, + CURVE_LINEAR = 9 } MEDCouplingMeshType; class DataArrayInt; @@ -48,6 +49,7 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingMesh : public RefCountObject, public TimeLabel { public: + std::size_t getHeapMemorySize() const; void setName(const char *name) { _name=name; } const char *getName() const { return _name.c_str(); } void setDescription(const char *descr) { _description=descr; } @@ -82,6 +84,10 @@ namespace ParaMEDMEM virtual int getMeshDimension() const = 0; virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; virtual DataArrayDouble *getBarycenterAndOwner() const = 0; + virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; virtual std::set getAllGeoTypes() const = 0; @@ -112,11 +118,17 @@ namespace ParaMEDMEM virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception); virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception) = 0; virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception) = 0; virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception); static MEDCouplingMesh *MergeMeshes(std::vector& meshes) throw(INTERP_KERNEL::Exception); + static bool IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static bool IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static INTERP_KERNEL::NormalizedCellType GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static int GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); //serialisation-unserialization @@ -130,6 +142,7 @@ namespace ParaMEDMEM void writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const throw(INTERP_KERNEL::Exception); /// @endcond virtual void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception) = 0; + virtual void reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception) = 0; protected: MEDCouplingMesh(); MEDCouplingMesh(const MEDCouplingMesh& other); diff --git a/src/MEDCoupling/MEDCouplingMultiFields.cxx b/src/MEDCoupling/MEDCouplingMultiFields.cxx index 94856e43d..963eed05c 100644 --- a/src/MEDCoupling/MEDCouplingMultiFields.cxx +++ b/src/MEDCoupling/MEDCouplingMultiFields.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -190,6 +190,22 @@ void MEDCouplingMultiFields::updateTime() const updateTimeWith(*(*it)); } +std::size_t MEDCouplingMultiFields::getHeapMemorySize() const +{ + std::vector tmp; + std::vector< std::vector > tmp2; + std::vector ms=getDifferentMeshes(tmp); + std::vector arrs=getDifferentArrays(tmp2); + std::size_t ret=0; + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) + if(*it) + ret+=(*it)->getHeapMemorySize(); + return ret; +} + std::vector MEDCouplingMultiFields::getMeshes() const throw(INTERP_KERNEL::Exception) { std::vector ms; @@ -326,8 +342,8 @@ MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& oth { if((const MEDCouplingFieldDouble *)other._fs[i]) { - MEDCouplingFieldTemplate *tmp=MEDCouplingFieldTemplate::New(other._fs[i]); - _fs[i]=MEDCouplingFieldDouble::New(tmp,other._fs[i]->getTimeDiscretization()); + MEDCouplingFieldTemplate *tmp=MEDCouplingFieldTemplate::New(*other._fs[i]); + _fs[i]=MEDCouplingFieldDouble::New(*tmp,other._fs[i]->getTimeDiscretization()); tmp->decrRef(); if(refs[i]!=-1) _fs[i]->setMesh(ms2[refs[i]]); @@ -421,7 +437,7 @@ void MEDCouplingMultiFields::finishUnserialization(const std::vector& tinyI int offD=0; for(int i=0;i tmp(sz3); for(int j=0;j getArrays() const throw(INTERP_KERNEL::Exception); virtual std::vector getDifferentArrays(std::vector< std::vector >& refs) const throw(INTERP_KERNEL::Exception); void updateTime() const; + std::size_t getHeapMemorySize() const; void getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const; void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& ft, const std::vector& ms, diff --git a/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/src/MEDCoupling/MEDCouplingNatureOfField.cxx index 818614ba0..3c44332fb 100644 --- a/src/MEDCoupling/MEDCouplingNatureOfField.cxx +++ b/src/MEDCoupling/MEDCouplingNatureOfField.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,6 +21,7 @@ #include "MEDCouplingNatureOfField.hxx" #include +#include namespace ParaMEDMEM { @@ -33,13 +34,37 @@ namespace ParaMEDMEM const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37}; - const char *MEDCouplingNatureOfField::getRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception) + const char *MEDCouplingNatureOfField::GetRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception) { const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat); if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES) - throw INTERP_KERNEL::Exception("MEDCouplingNatureOfField::getRepr : Unrecognized nature of field !"); + { + std::ostringstream oss; oss << "MEDCouplingNatureOfField::getRepr : Unrecognized nature of field ! "; + oss << GetAllPossibilitiesStr() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } std::size_t pos2=std::distance(POS_OF_NATUREOFFIELD,pos); return REPR_OF_NATUREOFFIELD[pos2]; } + + std::string MEDCouplingNatureOfField::GetReprNoThrow(NatureOfField nat) + { + const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat); + if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES) + return std::string("Unrecognized nature of field !"); + std::size_t pos2=std::distance(POS_OF_NATUREOFFIELD,pos); + return std::string(REPR_OF_NATUREOFFIELD[pos2]); + } + + std::string MEDCouplingNatureOfField::GetAllPossibilitiesStr() + { + std::ostringstream oss; oss << "Possibilities are : "; + for(int i=0;i -MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) +MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) { if(_mesh) _mesh->incrRef(); diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx index 4a2466b33..9c50cdaf2 100644 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx index 8a9da83cf..a1f52642f 100644 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index f2acae753..4cb2fd3c0 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -75,6 +75,14 @@ void MEDCouplingPointSet::updateTime() const } } +std::size_t MEDCouplingPointSet::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_coords) + ret+=_coords->getHeapMemorySize(); + return MEDCouplingMesh::getHeapMemorySize()+ret; +} + void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) { if( coords != _coords ) @@ -88,6 +96,11 @@ void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) } } +/*! + * Returns a pointer to the array of point coordinates held by \a this. + * \return DataArrayDouble * - the pointer to the array of point coordinates. The + * caller is to delete this array using decrRef() as it is no more needed. + */ DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const { if(_coords) @@ -96,8 +109,13 @@ DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const } /*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. + * Copies string attributes from an \a other mesh. The copied strings are + * - mesh name + * - mesh description + * - time units + * - textual data of the coordinates array (name and components info) + * + * \param [in] other - the mesh to copy string attributes from. */ void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) { @@ -126,6 +144,13 @@ bool MEDCouplingPointSet::isEqualIfNotWhy(const MEDCouplingMesh *other, double p return true; } +/*! + * Checks equality of point coordinates with coordinates of an \a other mesh. + * None textual data is considered. + * \param [in] other - the mesh to compare coordinates with \a this one. + * \param [in] prec - precision value to compare coordinates. + * \return bool - \a true if coordinates of points are equal, \a false else. + */ bool MEDCouplingPointSet::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const { const MEDCouplingPointSet *otherC=dynamic_cast(other); @@ -153,12 +178,26 @@ bool MEDCouplingPointSet::areCoordsEqualIfNotWhy(const MEDCouplingPointSet& othe return ret; } +/*! + * Checks equality of point coordinates with \a other point coordinates. + * Textual data (name and components info) \b is compared as well. + * \param [in] other - the point coordinates to compare with \a this one. + * \param [in] prec - precision value to compare coordinates. + * \return bool - \a true if coordinates of points are equal, \a false else. + */ bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const { std::string tmp; return areCoordsEqualIfNotWhy(other,prec,tmp); } +/*! + * Checks equality of point coordinates with \a other point coordinates. + * None textual data is considered. + * \param [in] other - the point coordinates to compare with \a this one. + * \param [in] prec - precision value to compare coordinates. + * \return bool - \a true if coordinates of points are equal, \a false else. + */ bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const { if(_coords==0 && other._coords==0) @@ -171,7 +210,16 @@ bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingP } /*! - * Returns coordinates of node with id 'nodeId' and append it in 'coo'. + * Returns coordinates of \a nodeId-th node. + * \param [in] nodeId - the ID of the node of interest. + * \param [in, out] coo - the array filled with coordinates of the \a nodeId-th + * node. This array is not cleared before filling in, the coordinates are + * appended to its end. + * \throw If the coordinates array is not set. + * \throw If \a nodeId is not a valid index for the coordinates array. + * + * \ref cpp_mcpointset_getcoordinatesofnode "Here is a C++ example".
+ * \ref py_mcpointset_getcoordinatesofnode "Here is a Python example". */ void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception) { @@ -192,31 +240,56 @@ void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector& } /*! - * This method is typically the base method used for implementation of mergeNodes. This method computes this permutation array using as input, - * This method is const ! So this method simply computes the array, no permutation of nodes is done. - * a precision 'precision' and a 'limitNodeId' that is the node id so that every nodes which id is strictly lower than 'limitNodeId' will not be merged. - * To desactivate this advanced feature put -1 to this argument. - * @param areNodesMerged output parameter that states if some nodes have been "merged" in returned array - * @param newNbOfNodes output parameter too this is the maximal id in returned array to avoid to recompute it. + * Finds nodes equal within \a precision and returns an array describing the + * permutation to remove duplicated nodes. + * \param [in] precision - minimal absolute distance between two nodes at which they are + * considered not coincident. + * \param [in] limitNodeId - limit node id. If all nodes within a group of coincident + * nodes have id strictly lower than \a limitTupleId then they are not + * returned. Put -1 to this parameter to have all nodes returned. + * \param [out] areNodesMerged - is set to \a true if any coincident nodes found. + * \param [out] newNbOfNodes - returns number of unique nodes. + * \return DataArrayInt * - the permutation array in "Old to New" mode. For more + * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. */ DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const { DataArrayInt *comm,*commI; findCommonNodes(precision,limitNodeId,comm,commI); int oldNbOfNodes=getNumberOfNodes(); - DataArrayInt *ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); areNodesMerged=(oldNbOfNodes!=newNbOfNodes); comm->decrRef(); commI->decrRef(); - return ret; + return ret.retn(); } /*! - * This methods searches for each node if there are any nodes in _coords that are less far than 'prec' from n1. if any, these nodes are stored in out params - * comm and commIndex. - * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged each other. - * @param comm out parameter (not inout) - * @param commIndex out parameter (not inout) + * Finds nodes coincident within \a prec tolerance. + * Ids of coincident nodes are stored in output arrays. + * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2". + * \param [in] prec - minimal absolute distance (using infinite norm) between two nodes at which they are + * considered not coincident. + * \param [in] limitNodeId - limit node id. If all nodes within a group of coincident + * nodes have id strictly lower than \a limitTupleId then they are not + * returned. Put -1 to this parameter to have all nodes treated. + * \param [out] comm - the array holding ids of coincident nodes. + * \a comm->getNumberOfComponents() == 1. + * \a comm->getNumberOfTuples() == \a commIndex->back(). The caller + * is to delete this array using decrRef() as it is no more needed. + * \param [out] commIndex - the array dividing all ids stored in \a comm into + * groups of (ids of) coincident nodes. Its every value is a tuple + * index where a next group of nodes begins. For example the second + * group of nodes in \a comm is described by following range of indices: + * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 + * gives the number of groups of coincident nodes. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * + * \ref cpp_mcpointset_findcommonnodes "Here is a C++ example".
+ * \ref py_mcpointset_findcommonnodes "Here is a Python example". */ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const { @@ -225,25 +298,61 @@ void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArra _coords->findCommonTuples(prec,limitNodeId,comm,commIndex); } -std::vector MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception) +/*! + * Finds nodes located at distances lower that \a eps from a given point. + * \param [in] pos - pointer to coordinates of the point. This array is expected to + * be of length \a this->getSpaceDimension() at least, else the + * behavior is not warranted. + * \param [in] eps - the lowest distance between a point and a node (using infinite norm) at which the node is + * not returned by this method. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of nodes + * close to the point. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * + * \ref cpp_mcpointset_getnodeidsnearpoint "Here is a C++ example".
+ * \ref py_mcpointset_getnodeidsnearpoint "Here is a Python example". + */ +DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception) { - std::vector c,cI; + DataArrayInt *c=0,*cI=0; getNodeIdsNearPoints(pos,1,eps,c,cI); + MEDCouplingAutoRefCountObjectPtr cITmp(cI); return c; } /*! - * Given a point given by its position 'pos' this method finds the set of node ids that are a a distance lower than eps. - * Position 'pos' is expected to be of size getSpaceDimension()*nbOfNodes. If not the behabiour is not warranted. - * This method throws an exception if no coordiantes are set. + * Finds nodes located at distances lower that \a eps from given points. + * \param [in] pos - pointer to coordinates of the points. This array is expected to + * be of length \a nbOfPoints * \a this->getSpaceDimension() at least, else the + * behavior is not warranted. + * \param [in] nbOfPoints - number of points whose coordinates are given by \a pos + * parameter. + * \param [in] eps - the lowest distance between (using infinite norm) a point and a node at which the node is + * not returned by this method. + * \param [out] c - array returning ids of nodes located closer than \a eps to the + * given points. The caller + * is to delete this array using decrRef() as it is no more needed. + * \param [out] cI - for each i-th given point, the array specifies tuples of \a c + * holding ids of nodes close to the i-th point.
The i-th value of \a cI is an + * index of tuple of \a c holding id of a first (if any) node close to the + * i-th given point. Difference between the i-th and (i+1)-th value of \a cI + * (i.e. \a cI[ i+1 ] - \a cI[ i ]) defines number of nodes close to the i-th + * point (that can be zero!). For example, the group of nodes close to the + * second point is described by following range of indices [ \a cI[1], \a cI[2] ). + * The caller is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * + * \ref cpp_mcpointset_getnodeidsnearpoints "Here is a C++ example".
+ * \ref py_mcpointset_getnodeidsnearpoints "Here is a Python example". */ -void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception) +void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception) { if(!_coords) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !"); int spaceDim=getSpaceDimension(); MEDCouplingAutoRefCountObjectPtr points=DataArrayDouble::New(); - points->useArray(pos,false,CPP_DEALLOC,nbOfNodes,spaceDim); + points->useArray(pos,false,CPP_DEALLOC,nbOfPoints,spaceDim); _coords->computeTupleIdsNearTuples(points,eps,c,cI); } @@ -257,7 +366,7 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const { if(!_coords) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); - return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm,commIndex,newNbOfNodes); + return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); } /* @@ -308,9 +417,17 @@ void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfN } /*! - * This method fills bbox params like that : bbox[0]=XMin, bbox[1]=XMax, bbox[2]=YMin... - * The returned bounding box is arranged along trihedron. - * @param bbox out array of size 2*this->getSpaceDimension(). + * Computes the minimum box bounding all nodes. The edges of the box are parallel to + * the Cartesian coordinate axes. The bounding box is described by coordinates of its + * two extremum points with minimal and maximal coordinates. + * \param [out] bbox - array filled with coordinates of extremum points in "no + * interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin, zMax (if in 3D). This + * array, of length 2 * \a this->getSpaceDimension() at least, is to be + * pre-allocated by the caller. + * \throw If the coordinates array is not set. + * + * \ref cpp_mcpointset_getBoundingBox "Here is a C++ example".
+ * \ref py_mcpointset_getBoundingBox "Here is a Python example". */ void MEDCouplingPointSet::getBoundingBox(double *bbox) const throw(INTERP_KERNEL::Exception) { @@ -320,7 +437,9 @@ void MEDCouplingPointSet::getBoundingBox(double *bbox) const throw(INTERP_KERNEL } /*! - * This method removes useless nodes in coords. + * Removes "free" nodes, i.e. nodes not used to define any element. + * \throw If the coordinates array is not set. + * \throw If the elements are not defined. */ void MEDCouplingPointSet::zipCoords() { @@ -335,9 +454,9 @@ struct MEDCouplingCompAbs }; /*! - * This method expects that _coords attribute is set. - * @return the carateristic dimension of point set. This caracteristic dimension is the max of difference - * @exception If _coords attribute not set. + * Returns the carateristic dimension of \a this point set, that is a maximal + * absolute values of node coordinates. + * \throw If the coordinates array is not set. */ double MEDCouplingPointSet::getCaracteristicDimension() const { @@ -352,9 +471,9 @@ double MEDCouplingPointSet::getCaracteristicDimension() const * This method recenter coordinates of nodes in \b this in order to be centered at the origin to benefit about the advantages of the precision to be around the box * around origin of 'radius' 1. * + * \warning this method is non const and alterates coordinates in \b this without modifying. * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed. * - * \warning this method is non const and alterates coordinates in \b this without modifying. */ void MEDCouplingPointSet::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception) { @@ -365,12 +484,22 @@ void MEDCouplingPointSet::recenterForMaxPrecision(double eps) throw(INTERP_KERNE } /*! - * Non const method that operates a rotation of 'this'. - * If spaceDim==2 'vector' parameter is ignored (and could be 0) and the rotation is done around 'center' with angle specified by 'angle'. - * If spaceDim==3 the rotation axe is defined by ('center','vector') and the angle is 'angle'. - * @param center an array of size getSpaceDimension(). - * @param vector in array of size getSpaceDimension(). - * @param angle angle of rotation in radian. + * Rotates \a this set of nodes by \a angle around either an axis (in 3D) or a point + * (in 2D). + * \param [in] center - coordinates either of an origin of rotation axis (in 3D) or + * of center of rotation (in 2D). This array is to be of size \a + * this->getSpaceDimension() at least. + * \param [in] vector - 3 components of a vector defining direction of the rotation + * axis in 3D. In 2D this parameter is not used. + * \param [in] angle - the rotation angle in radians. + * \throw If the coordinates array is not set. + * \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3. + * \throw If \a center == NULL + * \throw If \a vector == NULL && \a this->getSpaceDimension() == 3. + * \throw If Magnitude of \a vector is zero. + * + * \ref cpp_mcpointset_rotate "Here is a C++ example".
+ * \ref py_mcpointset_rotate "Here is a Python example". */ void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle) { @@ -386,11 +515,21 @@ void MEDCouplingPointSet::rotate(const double *center, const double *vector, dou } /*! - * Non const method that operates a translation of 'this'. - * @param vector in array of size getSpaceDimension(). + * Translates \a this set of nodes. + * \param [in] vector - components of a translation vector. This array is to be of + * size \a this->getSpaceDimension() at least. + * \throw If the coordinates array is not set. + * \throw If \a vector == NULL. + * + * \ref cpp_mcpointset_translate "Here is a C++ example".
+ * \ref py_mcpointset_translate "Here is a Python example". */ void MEDCouplingPointSet::translate(const double *vector) { + if(!vector) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : NULL input vector !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : no coordinates set !"); double *coords=_coords->getPointer(); int nbNodes=getNumberOfNodes(); int dim=getSpaceDimension(); @@ -401,35 +540,47 @@ void MEDCouplingPointSet::translate(const double *vector) updateTime(); } + /*! - * Non const method that operates a scale on 'this' with 'point' as reference point of scale and with factor 'factor'. - * @param point in array of size getSpaceDimension(). - * @param factor factor of the scaling + * Applies scaling transformation to \a this set of nodes. + * \param [in] point - coordinates of a scaling center. This array is to be of + * size \a this->getSpaceDimension() at least. + * \param [in] factor - a scale factor. + * \throw If the coordinates array is not set. + * \throw If \a point == NULL. + * + * \ref cpp_mcpointset_scale "Here is a C++ example".
+ * \ref py_mcpointset_scale "Here is a Python example". */ void MEDCouplingPointSet::scale(const double *point, double factor) { + if(!point) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : NULL input point !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : no coordinates set !"); double *coords=_coords->getPointer(); int nbNodes=getNumberOfNodes(); int dim=getSpaceDimension(); - double *tmp=new double[dim]; for(int i=0;i()); std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies(),factor)); std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus()); } - delete [] tmp; _coords->declareAsNew(); updateTime(); } /*! - * This method is only available for already defined coordinates. - * If not an INTERP_KERNEL::Exception is thrown. The 'newSpaceDim' input must be greater or equal to 1. - * This method simply convert this to newSpaceDim space : - * - by putting a 0. for each \f$ i^{th} \f$ components of each coord of nodes so that i>=getSpaceDim(), if 'newSpaceDim'>getSpaceDimsion() - * - by ignoring each \f$ i^{th} \f$ components of each coord of nodes so that i >= 'newSpaceDim', 'newSpaceDim'getSpaceDimension(), nothing is done. + * \param [in] newSpaceDim - the new space dimension. + * \param [in] dftValue - the value to assign to added components of point coordinates + * (if the dimension increases). + * \throw If the coordinates array is not set. + * \throw If \a newSpaceDim < 1. */ void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim, double dftValue) throw(INTERP_KERNEL::Exception) { @@ -447,8 +598,14 @@ void MEDCouplingPointSet::changeSpaceDimension(int newSpaceDim, double dftValue) } /*! - * This method try to substitute this->_coords with other._coords if arrays match. - * This method potentially modifies 'this' if it succeeds, otherway an exception is thrown. + * Substitutes \a this->_coords with \a other._coords provided that coordinates of + * the two point sets match with a specified precision, else an exception is thrown. + * \param [in] other - the other point set whose coordinates array will be used by + * \a this point set in case of their equality. + * \param [in] epsilon - the precision used to compare coordinates. + * \throw If the coordinates array of \a this is not set. + * \throw If the coordinates array of \a other is not set. + * \throw If the coordinates of \a this and \a other do not match. */ void MEDCouplingPointSet::tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) { @@ -480,21 +637,33 @@ void MEDCouplingPointSet::duplicateNodesInCoords(const int *nodeIdsToDuplicateBg } /*! - * This method is expecting to be called for meshes so that getSpaceDimension() returns 3. - * This method returns in 'nodes' output all the nodes that are at a distance lower than epsilon from plane - * defined by the point 'pt' and the vector 'vec'. - * @param pt points to an array of size 3 and represents a point that owns to plane. - * @param vec points to an array of size 3 and represents the normal vector of the plane. The norm of the vector is not compulsory equal to 1. But norm must be greater than 10*abs(eps) - * @param eps is the maximal distance around the plane where node in this->_coords will be picked. - * @param nodes is the output of the method. The vector is not compulsory empty before call. The nodes that fulfills the condition will be added at the end of the nodes. + * Finds nodes located at distance lower that \a eps from a specified plane. + * \param [in] pt - 3 components of a point defining location of the plane. + * \param [in] vec - 3 components of a normal vector to the plane. Vector magnitude + * must be greater than 10*\a eps. + * \param [in] eps - maximal distance of a node from the plane at which the node is + * considered to lie on the plane. + * \param [in,out] nodes - a vector returning ids of found nodes. This vector is not + * cleared before filling in. + * \throw If the coordinates array is not set. + * \throw If \a pt == NULL. + * \throw If \a vec == NULL. + * \throw If the magnitude of \a vec is zero. + * \throw If \a this->getSpaceDimension() != 3. */ void MEDCouplingPointSet::findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const throw(INTERP_KERNEL::Exception) { if(getSpaceDimension()!=3) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : Invalid spacedim to be applied on this ! Must be equal to 3 !"); + if(!pt) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : NULL point pointer specified !"); + if(!vec) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : NULL vector pointer specified !"); int nbOfNodes=getNumberOfNodes(); double a=vec[0],b=vec[1],c=vec[2],d=-pt[0]*vec[0]-pt[1]*vec[1]-pt[2]*vec[2]; double deno=sqrt(a*a+b*b+c*c); + if(deno::min()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : vector pointer specified has norm equal to 0. !"); const double *work=_coords->getConstPointer(); for(int i=0;igetSpaceDimension and represents a point that owns to plane. - * @param vec points to an array of size this->getSpaceDimension and represents the direction vector of the line. The norm of the vector is not compulsory equal to 1. - * But norm must be greater than 10*abs(eps) - * @param eps is the maximal distance around the plane where node in this->_coords will be picked. - * @param nodes is the output of the method. The vector is not compulsory empty before call. The nodes that fulfills the condition will be added at the end of the nodes. + * Finds nodes located at distance lower that \a eps from a specified line in 2D and 3D. + * \param [in] pt - components of coordinates of an initial point of the line. This + * array is to be of size \a this->getSpaceDimension() at least. + * \param [in] vec - components of a vector defining the line direction. This array + * is to be of size \a this->getSpaceDimension() at least. Vector magnitude + * must be greater than 10*\a eps. + * \param [in] eps - maximal distance of a node from the line at which the node is + * considered to lie on the line. + * \param [in,out] nodes - a vector returning ids of found nodes. This vector is not + * cleared before filling in. + * \throw If the coordinates array is not set. + * \throw If \a pt == NULL. + * \throw If \a vec == NULL. + * \throw If the magnitude of \a vec is zero. + * \throw If ( \a this->getSpaceDimension() != 3 && \a this->getSpaceDimension() != 2 ). */ void MEDCouplingPointSet::findNodesOnLine(const double *pt, const double *vec, double eps, std::vector& nodes) const throw(INTERP_KERNEL::Exception) { int spaceDim=getSpaceDimension(); if(spaceDim!=2 && spaceDim!=3) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : Invalid spacedim to be applied on this ! Must be equal to 2 or 3 !"); + if(!pt) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : NULL point pointer specified !"); + if(!vec) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : NULL vector pointer specified !"); int nbOfNodes=getNumberOfNodes(); double den=0.; for(int i=0;igetSpaceDimension() != \a m2->getSpaceDimension(). */ DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception) { @@ -703,6 +895,12 @@ void MEDCouplingPointSet::unserialization(const std::vector& tinyInfoD, } } +void MEDCouplingPointSet::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !"); +} + /*! * Intersect Bounding Box given 2 Bounding Boxes. */ @@ -790,6 +988,8 @@ void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double matrix[9]; double matrixTmp[9]; double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]); + if(norm::min()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : magnitude of input vector is too close of 0. !"); std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies(),1/norm)); //rotation matrix computation matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa; @@ -815,10 +1015,14 @@ void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, } /*! - * This method implements pure virtual method MEDCouplingMesh::buildPart. - * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end'). - * The coords are kept unchanged contrary to pure virtual method MEDCouplingMesh::buildPartAndReduceNodes. - * The returned mesh has to be managed by the caller. + * Creates a new MEDCouplingMesh containing a part of cells of \a this mesh. The new + * mesh shares a coordinates array with \a this one. The cells to include to the + * result mesh are specified by an array of cell ids. + * \param [in] start - an array of cell ids to include to the result mesh. + * \param [in] end - specifies the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. */ MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end) const { @@ -826,21 +1030,51 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end } /*! - * This method implements pure virtual method MEDCouplingMesh::buildPartAndReduceNodes. - * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end') \b and potentially reduces the nodes set - * behind returned mesh. This cause an overhead but it is lesser in memory. - * This method returns an array too. This array allows to the caller to know the mapping between nodeids in 'this' and nodeids in - * returned mesh. This is quite usefull for MEDCouplingFieldDouble on nodes for example... - * 'arr' is in old2New format of size ret->getNumberOfCells like MEDCouplingUMesh::zipCoordsTraducer is. - * The returned mesh has to be managed by the caller. + * Creates a new MEDCouplingMesh containing a part of cells of \a this mesh. The + * cells to include to the result mesh are specified by an array of cell ids. + *
This method additionally returns a renumbering map in "Old to New" mode + * which allows the caller to know the mapping between nodes in \a this and the result mesh. + * \param [in] start - an array of cell ids to include to the result mesh. + * \param [in] end - specifies the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \param [out] arr - a new DataArrayInt that is the "Old to New" renumbering + * map. The caller is to delete this array using decrRef() as it is no more needed. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. */ MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const { - MEDCouplingPointSet *ret=buildPartOfMySelf(start,end,true); + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf(start,end,true); arr=ret->zipCoordsTraducer(); - return ret; + return ret.retn(); } +/*! + * This method specialized the MEDCouplingMesh::buildPartRange + * + * \sa MEDCouplingUMesh::buildPartOfMySelf2 + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) +{ + return buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); +} + +/*! + * This method specialized the MEDCouplingMesh::buildPartRangeAndReduceNodes + * + * \param [out] beginOut valid only if \a arr not NULL ! + * \param [out] endOut valid only if \a arr not NULL ! + * \param [out] stepOut valid only if \a arr not NULL ! + * \param [out] arr correspondance old to new in node ids. + * + * \sa MEDCouplingUMesh::buildPartOfMySelf2 + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf2(beginCellIds,endCellIds,stepCellIds,true); + arr=ret->zipCoordsTraducer(); + return ret.retn(); +} /*! * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect' diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 4e00e4770..e0ef76118 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -52,12 +52,11 @@ namespace ParaMEDMEM ~MEDCouplingPointSet(); public: void updateTime() const; + std::size_t getHeapMemorySize() const; int getNumberOfNodes() const; int getSpaceDimension() const; void setCoords(const DataArrayDouble *coords); - //! This method returns directly the array in 'this' \b without incrementing ref counter. The pointer is dealed by the mesh. The caller should not deal (decrRef) with this pointer const DataArrayDouble *getCoords() const { return _coords; } - //! This method returns directly the array in 'this' \b without incrementing ref counter. The pointer is dealed by the mesh. The caller should not deal (decrRef) with this pointer DataArrayDouble *getCoords() { return _coords; } DataArrayDouble *getCoordinatesAndOwner() const; void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); @@ -70,8 +69,8 @@ namespace ParaMEDMEM virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; void getCoordinatesOfNode(int nodeId, std::vector& coo) const throw(INTERP_KERNEL::Exception); DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; - std::vector getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); - void getNodeIdsNearPoints(const double *pos, int nbOfNodes, double eps, std::vector& c, std::vector& cI) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const throw(INTERP_KERNEL::Exception); + void getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception); void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, int& newNbOfNodes) const; @@ -95,6 +94,8 @@ namespace ParaMEDMEM static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); MEDCouplingMesh *buildPart(const int *start, const int *end) const; MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception); virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const = 0; virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; @@ -104,16 +105,16 @@ namespace ParaMEDMEM virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; - //! size of returned tinyInfo must be always the same. void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); - virtual void getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const = 0; - virtual void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) = 0; + virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; + virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; virtual DataArrayInt *zipCoordsTraducer() = 0; protected: + void checkCoherency() const throw(INTERP_KERNEL::Exception); virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception) = 0; static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); diff --git a/src/MEDCoupling/MEDCouplingRefCountObject.cxx b/src/MEDCoupling/MEDCouplingRefCountObject.cxx index e55612456..b4ae45f67 100644 --- a/src/MEDCoupling/MEDCouplingRefCountObject.cxx +++ b/src/MEDCoupling/MEDCouplingRefCountObject.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,11 @@ void ParaMEDMEM::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas) releas=(ver & 0xFF); } +int ParaMEDMEM::MEDCouplingSizeOfVoidStar() +{ + return 8*sizeof(std::size_t); +} + RefCountObject::RefCountObject():_cnt(1) { } diff --git a/src/MEDCoupling/MEDCouplingRefCountObject.hxx b/src/MEDCoupling/MEDCouplingRefCountObject.hxx index c6eb6825a..7d8c1904b 100644 --- a/src/MEDCoupling/MEDCouplingRefCountObject.hxx +++ b/src/MEDCoupling/MEDCouplingRefCountObject.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,8 @@ #include "MEDCoupling.hxx" +#include + namespace ParaMEDMEM { typedef enum @@ -53,6 +55,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr(); MEDCOUPLING_EXPORT int MEDCouplingVersion(); MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas); + MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar(); class MEDCOUPLING_EXPORT RefCountObject { @@ -62,6 +65,7 @@ namespace ParaMEDMEM public: bool decrRef() const; void incrRef() const; + virtual std::size_t getHeapMemorySize() const = 0; protected: virtual ~RefCountObject(); private: diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx index 8a489b139..45355f150 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ b/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -40,7 +40,7 @@ using namespace ParaMEDMEM; -MEDCouplingRemapper::MEDCouplingRemapper():_src_mesh(0),_target_mesh(0),_nature_of_deno(NoNature),_time_deno_update(0) +MEDCouplingRemapper::MEDCouplingRemapper():_src_ft(0),_target_ft(0),_interp_matrix_pol(IK_ONLY_PREFERED),_nature_of_deno(NoNature),_time_deno_update(0) { } @@ -51,32 +51,66 @@ MEDCouplingRemapper::~MEDCouplingRemapper() int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception) { + if(!srcMesh || !targetMesh) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepare : presence of NULL input pointer !"); + std::string srcMethod,targetMethod; + INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method,srcMethod,targetMethod); + MEDCouplingAutoRefCountObjectPtr src=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(srcMethod.c_str())); + src->setMesh(srcMesh); + MEDCouplingAutoRefCountObjectPtr target=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(targetMethod.c_str())); + target->setMesh(targetMesh); + return prepareEx(src,target); +} + +int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception) +{ + if(!src || !target) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL input pointer !"); + if(!src->getMesh() || !target->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL mesh pointer in given field template !"); releaseData(true); - _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(); + _src_ft=const_cast(src); _src_ft->incrRef(); + _target_ft=const_cast(target); _target_ft->incrRef(); + if(isInterpKernelOnlyOrNotOnly()) + return prepareInterpKernelOnly(); + else + return prepareNotInterpKernelOnly(); +} + +int MEDCouplingRemapper::prepareInterpKernelOnly() throw(INTERP_KERNEL::Exception) +{ + int meshInterpType=((int)_src_ft->getMesh()->getType()*16)+(int)_target_ft->getMesh()->getType(); switch(meshInterpType) { case 85://Unstructured-Unstructured - return prepareUU(method); + return prepareInterpKernelOnlyUU(); case 87://Unstructured-Cartesian - return prepareUC(method); + return prepareInterpKernelOnlyUC(); case 117://Cartesian-Unstructured - return prepareCU(method); + return prepareInterpKernelOnlyCU(); case 119://Cartesian-Cartesian - return prepareCC(method); + return prepareInterpKernelOnlyCC(); case 136://Extruded-Extruded - return prepareEE(method); + return prepareInterpKernelOnlyEE(); default: - throw INTERP_KERNEL::Exception("Not managed type of meshes !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnly : Not managed type of meshes ! Dealt meshes type are : Unstructured<->Unstructured, Unstructured<->Cartesian, Cartesian<->Cartesian, Extruded<->Extruded !"); } } -int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareNotInterpKernelOnly() throw(INTERP_KERNEL::Exception) { - std::string meth(src->getDiscretization()->getStringRepr()); - meth+=target->getDiscretization()->getStringRepr(); - return prepare(src->getMesh(),target->getMesh(),meth.c_str()); + std::string srcm,trgm,method; + method=checkAndGiveInterpolationMethodStr(srcm,trgm); + switch(CheckInterpolationMethodManageableByNotOnlyInterpKernel(method)) + { + case 0: + return prepareNotInterpKernelOnlyGaussGauss(); + default: + { + std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnly : INTERNAL ERROR ! the method \"" << method << "\" declared as managed bu not implemented !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } } /*! @@ -107,9 +141,10 @@ void MEDCouplingRemapper::partialTransfer(const MEDCouplingFieldDouble *srcField void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); if(srcField->getNature()!=targetField->getNature()) throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); @@ -135,48 +170,129 @@ void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, cons MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(_target_method.c_str()),srcField->getTimeDiscretization()); - ret->copyTinyAttrFrom(srcField); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_target_ft,srcField->getTimeDiscretization()); ret->setNature(srcField->getNature()); - ret->setMesh(_target_mesh); transfer(srcField,ret,dftValue); + ret->copyAllTinyAttrFrom(srcField);//perform copy of tiny strings after and not before transfer because the array will be created on transfer return ret; } MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(_target_method.c_str()),targetField->getTimeDiscretization()); - ret->copyTinyAttrFrom(targetField); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_src_ft,targetField->getTimeDiscretization()); ret->setNature(targetField->getNature()); - ret->setMesh(_src_mesh); reverseTransfer(ret,targetField,dftValue); + ret->copyAllTinyAttrFrom(targetField);//perform copy of tiny strings after and not before reverseTransfer because the array will be created on reverseTransfer return ret; } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionInt(const std::string& key, int value) { return INTERP_KERNEL::InterpolationOptions::setOptionInt(key,value); } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value) { return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value); } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value) { return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value); } -int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exception) +/*! + * This method returns the interpolation matrix policy. This policy specifies which interpolation matrix method to keep or prefered. + * If interpolation matrix policy is : + * + * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. + * If not, the \b not only INTERP_KERNEL method will be attempt. + * + * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. + * If not, the INTERP_KERNEL only method will be attempt. + * + * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. + * + * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. + * + * \sa MEDCouplingRemapper::setInterpolationMatrixPolicy + */ +int MEDCouplingRemapper::getInterpolationMatrixPolicy() const +{ + return _interp_matrix_pol; +} + +/*! + * This method sets a new interpolation matrix policy. The default one is IK_PREFERED (0). The input is of type \c int to be dealt by standard Salome + * CORBA component generators. This method throws an INTERP_KERNEL::Exception if a the input integer is not in the available possibilities, that is to say not in + * [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)]. + * + * If interpolation matrix policy is : + * + * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. + * If not, the \b not only INTERP_KERNEL method will be attempt. + * + * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. + * If not, the INTERP_KERNEL only method will be attempt. + * + * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. + * + * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. + * + * \input newInterpMatPol the new interpolation matrix method policy. This parameter is of type \c int and not of type \c ParaMEDMEM::InterpolationMatrixPolicy + * for automatic generation of CORBA component. + * + * \sa MEDCouplingRemapper::getInterpolationMatrixPolicy + */ +void MEDCouplingRemapper::setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception) +{ + switch(newInterpMatPol) + { + case 0: + _interp_matrix_pol=IK_ONLY_PREFERED; + break; + case 1: + _interp_matrix_pol=NOT_IK_ONLY_PREFERED; + break; + case 2: + _interp_matrix_pol=IK_ONLY_FORCED; + break; + case 3: + _interp_matrix_pol=NOT_IK_ONLY_FORCED; + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::setInterpolationMatrixPolicy : invalid input integer value ! Should be in [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)] ! For information, the default is IK_PREFERED=0 !"); + } +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyUU() throw(INTERP_KERNEL::Exception) { - MEDCouplingUMesh *src_mesh=(MEDCouplingUMesh *)_src_mesh; - MEDCouplingUMesh *target_mesh=(MEDCouplingUMesh *)_target_mesh; - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); + const MEDCouplingUMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingUMesh *target_mesh=static_cast(_target_ft->getMesh()); + std::string srcMeth,trgMeth; + std::string method=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); const int srcMeshDim=src_mesh->getMeshDimension(); int srcSpaceDim=-1; if(srcMeshDim!=-1) @@ -194,35 +310,35 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<1,1> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<1,1> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==2) { MEDCouplingNormalizedUnstructuredMesh<2,1> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,1> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2) { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==3 && trgMeshDim==3 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==3 && trgMeshDim==1 && srcSpaceDim==3) { @@ -231,7 +347,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3) { @@ -241,7 +357,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -252,7 +368,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else { @@ -260,7 +376,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D1D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -284,7 +400,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -293,7 +409,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); if(!duplicateFaces.empty()) { @@ -312,7 +428,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); if(!duplicateFaces.empty()) { @@ -331,7 +447,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -352,19 +468,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else if(srcMeshDim==3 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else if(srcMeshDim==2 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); @@ -375,19 +491,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else if(trgMeshDim==3 && trgSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else if(trgMeshDim==2 && trgSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh from -1D sourceMesh"); @@ -402,19 +518,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyEE() throw(INTERP_KERNEL::Exception) { - MEDCouplingExtrudedMesh *src_mesh=(MEDCouplingExtrudedMesh *)_src_mesh; - MEDCouplingExtrudedMesh *target_mesh=(MEDCouplingExtrudedMesh *)_target_mesh; - std::string methC(method); + std::string srcMeth,trgMeth; + std::string methC=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + const MEDCouplingExtrudedMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingExtrudedMesh *target_mesh=static_cast(_target_ft->getMesh()); if(methC!="P0P0") - throw INTERP_KERNEL::Exception("Only P0P0 method implemented for Extruded/Extruded meshes !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyEE : Only P0P0 method implemented for Extruded/Extruded meshes !"); MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh->getMesh2D()); MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh->getMesh2D()); INTERP_KERNEL::Interpolation3DSurf interpolation2D(*this); std::vector > matrix2D; - int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,method); + int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,methC.c_str()); MEDCouplingUMesh *s1D,*t1D; double v[3]; MEDCouplingExtrudedMesh::Project1DMeshes(src_mesh->getMesh1D(),target_mesh->getMesh1D(),getPrecision(),s1D,t1D,v); @@ -422,7 +538,7 @@ int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<1,1> t1DWrapper(t1D); std::vector > matrix1D; INTERP_KERNEL::Interpolation1D interpolation1D(*this); - int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,method); + int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,methC.c_str()); s1D->decrRef(); t1D->decrRef(); buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D, @@ -436,19 +552,19 @@ int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyUC() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingUMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingCMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingUMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int srcSpceDim=src_mesh->getSpaceDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); if(srcMeshDim!=srcSpceDim || srcMeshDim!=trgMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !"); std::vector > res; switch(srcMeshDim) { @@ -477,7 +593,7 @@ int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !"); } ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix); nullifiedTinyCoeffInCrudeMatrixAbs(0.); @@ -490,19 +606,19 @@ int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyCU() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingCMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingUMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingUMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); const int trgSpceDim=target_mesh->getSpaceDimension(); if(trgMeshDim!=trgSpceDim || trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !"); switch(srcMeshDim) { case 1: @@ -530,7 +646,7 @@ int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !"); } nullifiedTinyCoeffInCrudeMatrixAbs(0.); // @@ -542,18 +658,18 @@ int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyCC() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingCMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingCMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); if(trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); switch(srcMeshDim) { case 1: @@ -581,7 +697,7 @@ int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !"); } nullifiedTinyCoeffInCrudeMatrixAbs(0.); // @@ -593,18 +709,162 @@ int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exce return 1; } +int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss() throw(INTERP_KERNEL::Exception) +{ + if(getIntersectionType()!=INTERP_KERNEL::PointLocator) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : The intersection type is not supported ! Only PointLocator is supported for Gauss->Gauss interpolation ! Please invoke setIntersectionType(PointLocator) on the MEDCouplingRemapper instance !"); + MEDCouplingAutoRefCountObjectPtr trgLoc=_target_ft->getLocalizationOfDiscr(); + const double *trgLocPtr=trgLoc->begin(); + int trgSpaceDim=trgLoc->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr srcOffsetArr=_src_ft->getDiscretization()->getOffsetArr(_src_ft->getMesh()); + if(trgSpaceDim!=_src_ft->getMesh()->getSpaceDimension()) + { + std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : space dimensions mismatch between source and target !"; + oss << " Target discretization localization has dimension " << trgSpaceDim << ", whereas the space dimension of source is equal to "; + oss << _src_ft->getMesh()->getSpaceDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const int *srcOffsetArrPtr=srcOffsetArr->begin(); + MEDCouplingAutoRefCountObjectPtr srcLoc=_src_ft->getLocalizationOfDiscr(); + const double *srcLocPtr=srcLoc->begin(); + std::vector elts,eltsIndex; + int trgNbOfGaussPts=trgLoc->getNumberOfTuples(); + _matrix.resize(trgNbOfGaussPts); + _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),elts,eltsIndex); + MEDCouplingAutoRefCountObjectPtr eltsIndex2=DataArrayInt::New(); eltsIndex2->useArray(&eltsIndex[0],false,CPP_DEALLOC,(int)eltsIndex.size(),1); + MEDCouplingAutoRefCountObjectPtr nbOfSrcCellsShTrgPts=eltsIndex2->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr ids0=nbOfSrcCellsShTrgPts->getIdsNotEqual(0); + for(const int *trgId=ids0->begin();trgId!=ids0->end();trgId++) + { + const double *ptTrg=trgLocPtr+trgSpaceDim*(*trgId); + int srcCellId=elts[eltsIndex[*trgId]]; + double dist=std::numeric_limits::max(); + int srcEntry=-1; + for(int srcId=srcOffsetArrPtr[srcCellId];srcIdgetNumberOfTuples()!=trgNbOfGaussPts) + { + MEDCouplingAutoRefCountObjectPtr orphanTrgIds=nbOfSrcCellsShTrgPts->getIdsEqual(0); + MEDCouplingAutoRefCountObjectPtr orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end()); + MEDCouplingAutoRefCountObjectPtr srcIdPerTrg=srcLoc->findClosestTupleId(orphanTrg); + const int *srcIdPerTrgPtr=srcIdPerTrg->begin(); + for(const int *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++) + _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.; + } + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(srcLoc->getNumberOfTuples()); + declareAsNew(); + return 1; +} + +/*! + * This method checks that the input interpolation \a method is managed by not INTERP_KERNEL only methods. + * If no an INTERP_KERNEL::Exception will be thrown. If yes, a magic number will be returned to switch in the MEDCouplingRemapper::prepareNotInterpKernelOnly method. + */ +int MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method) throw(INTERP_KERNEL::Exception) +{ + if(method=="GAUSSGAUSS") + return 0; + std::ostringstream oss; oss << "MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel : "; + oss << "The method \"" << method << "\" is not manageable by not INTERP_KERNEL only method."; + oss << " Not only INTERP_KERNEL methods dealed are : GAUSSGAUSS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * This method determines regarding \c _interp_matrix_pol attribute ( set by MEDCouplingRemapper::setInterpolationMatrixPolicy and by default equal + * to IK_ONLY_PREFERED = 0 ) , which method will be applied. If \c true is returned the INTERP_KERNEL only method should be applied to \c false the \b not + * only INTERP_KERNEL method should be applied. + */ +bool MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly() const throw(INTERP_KERNEL::Exception) +{ + std::string srcm,trgm,method; + method=checkAndGiveInterpolationMethodStr(srcm,trgm); + switch(_interp_matrix_pol) + { + case IK_ONLY_PREFERED: + { + try + { + std::string tmp1,tmp2; + INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method.c_str(),tmp1,tmp2); + return true; + } + catch(INTERP_KERNEL::Exception& e) + { + return false; + } + } + case NOT_IK_ONLY_PREFERED: + { + try + { + CheckInterpolationMethodManageableByNotOnlyInterpKernel(method); + return false; + } + catch(INTERP_KERNEL::Exception& e) + { + return true; + } + } + case IK_ONLY_FORCED: + return true; + case NOT_IK_ONLY_FORCED: + return false; + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly : internal error ! The interpolation matrix policy is not managed ! Try to change it using MEDCouplingRemapper::setInterpolationMatrixPolicy !"); + } +} + void MEDCouplingRemapper::updateTime() const { } +void MEDCouplingRemapper::checkPrepare() const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); + if(!s || !t) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that MEDCouplingRemapper::prepare(Ex) has not been called !"); + if(!s->getMesh() || !t->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that no all field templates have their mesh set !"); +} + +/*! + * This method builds a code considering already set field discretization int \a this : \a _src_ft and \a _target_ft. + * This method returns 3 informations (2 in ouput parameters and 1 in return). + * + * \param [out] srcMeth the string code of the discretization of source field template + * \param [out] trgMeth the string code of the discretization of target field template + * \return the standardized string code (compatible with INTERP_KERNEL) for matrix of numerators (in \a _matrix) + */ +std::string MEDCouplingRemapper::checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); + if(!s || !t) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have been set !"); + if(!s->getMesh() || !t->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have their mesh set !"); + srcMeth=_src_ft->getDiscretization()->getRepr(); + trgMeth=_target_ft->getDiscretization()->getRepr(); + std::string method(srcMeth); method+=trgMeth; + return method; +} + void MEDCouplingRemapper::releaseData(bool matrixSuppression) { - if(_src_mesh) - _src_mesh->decrRef(); - if(_target_mesh) - _target_mesh->decrRef(); - _src_mesh=0; - _target_mesh=0; + _src_ft=0; + _target_ft=0; if(matrixSuppression) { _matrix.clear(); @@ -615,9 +875,10 @@ void MEDCouplingRemapper::releaseData(bool matrixSuppression) void MEDCouplingRemapper::transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); if(srcField->getNature()!=targetField->getNature()) throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); @@ -666,8 +927,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case Integral: { - MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); - MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); + MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); + MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) @@ -698,8 +959,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case RevIntegral: { - MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); - MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); + MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),getMeasureAbsStatus()); + MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),getMeasureAbsStatus()); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx index 41948c2fb..f4d581345 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ b/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,8 @@ #include "MEDCouplingTimeLabel.hxx" #include "InterpolationOptions.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + #include "InterpKernelException.hxx" #include @@ -33,13 +35,20 @@ namespace ParaMEDMEM { class MEDCouplingMesh; - class MEDCouplingUMesh; class MEDCouplingFieldDouble; class MEDCouplingFieldTemplate; } namespace ParaMEDMEM { + typedef enum + { + IK_ONLY_PREFERED = 0, + NOT_IK_ONLY_PREFERED = 1, + IK_ONLY_FORCED = 2, + NOT_IK_ONLY_FORCED =3 + } InterpolationMatrixPolicy; + class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions { public: @@ -55,6 +64,8 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value); MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value); MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value); + MEDCOUPLINGREMAPPER_EXPORT int getInterpolationMatrixPolicy() const; + MEDCOUPLINGREMAPPER_EXPORT void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); // MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); @@ -63,12 +74,22 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT const std::vector >& getCrudeMatrix() const; MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector >& m); private: - int prepareUU(const char *method) throw(INTERP_KERNEL::Exception); - int prepareEE(const char *method) throw(INTERP_KERNEL::Exception); - int prepareUC(const char *method) throw(INTERP_KERNEL::Exception); - int prepareCU(const char *method) throw(INTERP_KERNEL::Exception); - int prepareCC(const char *method) throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnly() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyUU() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyEE() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyUC() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyCU() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyCC() throw(INTERP_KERNEL::Exception); + // + int prepareNotInterpKernelOnly() throw(INTERP_KERNEL::Exception); + int prepareNotInterpKernelOnlyGaussGauss() throw(INTERP_KERNEL::Exception); + // + static int CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method) throw(INTERP_KERNEL::Exception); + // + bool isInterpKernelOnlyOrNotOnly() const throw(INTERP_KERNEL::Exception); void updateTime() const; + void checkPrepare() const throw(INTERP_KERNEL::Exception); + std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const throw(INTERP_KERNEL::Exception); void releaseData(bool matrixSuppression); void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) throw(INTERP_KERNEL::Exception); void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); @@ -86,10 +107,9 @@ namespace ParaMEDMEM static void ComputeColSumAndRowSum(const std::vector >& matrixDeno, std::vector >& deno, std::vector >& denoReverse); private: - MEDCouplingMesh *_src_mesh; - MEDCouplingMesh *_target_mesh; - std::string _src_method; - std::string _target_method; + MEDCouplingAutoRefCountObjectPtr _src_ft; + MEDCouplingAutoRefCountObjectPtr _target_ft; + InterpolationMatrixPolicy _interp_matrix_pol; NatureOfField _nature_of_deno; unsigned int _time_deno_update; std::vector > _matrix; diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx new file mode 100644 index 000000000..407f956dc --- /dev/null +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -0,0 +1,425 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#include "MEDCouplingStructuredMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingUMesh.hxx" + +#include + +using namespace ParaMEDMEM; + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() +{ +} + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) +{ +} + +MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() +{ +} + +std::size_t MEDCouplingStructuredMesh::getHeapMemorySize() const +{ + return MEDCouplingMesh::getHeapMemorySize(); +} + +void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + MEDCouplingMesh::copyTinyStringsFrom(other); +} + +bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) +{ + return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const +{ + switch(getMeshDimension()) + { + case 3: + return INTERP_KERNEL::NORM_HEXA8; + case 2: + return INTERP_KERNEL::NORM_QUAD4; + case 1: + return INTERP_KERNEL::NORM_SEG2; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCurveLinearMesh::getTypeOfCell !"); + } +} + +std::set MEDCouplingStructuredMesh::getAllGeoTypes() const +{ + std::set ret2; + ret2.insert(getTypeOfCell(0)); + return ret2; +} + +int MEDCouplingStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + int ret=getNumberOfCells(); + if(type==getTypeOfCell(0)) + return ret; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCellsWithType : no specified type ! Type available is " << cm.getRepr() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +DataArrayInt *MEDCouplingStructuredMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + if(getTypeOfCell(0)==type) + { + ret->alloc(getNumberOfCells(),1); + ret->iota(0); + } + else + ret->alloc(0,1); + return ret.retn(); +} + +DataArrayInt *MEDCouplingStructuredMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbCells,1); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); + ret->fillWithValue((int)cm.getNumberOfNodes()); + return ret.retn(); +} + +DataArrayInt *MEDCouplingStructuredMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception) +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbCells,1); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getTypeOfCell(0)); + ret->fillWithValue((int)cm.getNumberOfSons()); + return ret.retn(); +} + +void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const +{ + int meshDim=getMeshDimension(); + int tmpCell[3],tmpNode[3]; + getSplitCellValues(tmpCell); + getSplitNodeValues(tmpNode); + int tmp2[3]; + GetPosFromId(cellId,meshDim,tmpCell,tmp2); + switch(meshDim) + { + case 1: + conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1); + break; + case 2: + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1); + conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]); + break; + case 3: + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); + conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !"); + }; +} + +/*! + * See MEDCouplingUMesh::getDistributionOfTypes for more information + */ +std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) +{ + //only one type of cell + std::vector ret(3); + ret[0]=getTypeOfCell(0); + ret[1]=getNumberOfCells(); + ret[2]=0; //ret[3*k+2]==0 because it has no sense here + return ret; +} + +/*! + * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information + */ +DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + if(code.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code is empty, should not !"); + std::size_t sz=code.size(); + if(sz!=3) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !"); + + int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]); + if(code[2]==-1) + { + if(code[1]==nbCells) + return 0; + else + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : number of cells mismatch !"); + } + else + { + if(code[2]<-1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !"); + if(code[2]>=(int)idsPerType.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !"); + return idsPerType[code[2]]->deepCpy(); + } +} + +/*! + * See MEDCouplingUMesh::splitProfilePerType for more information + */ +void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) +{ + int nbCells=getNumberOfCells(); + code.resize(3); + code[0]=(int)getTypeOfCell(0); + code[1]=nbCells; + code[2]=0; + idsInPflPerType.push_back(profile->deepCpy()); + idsPerType.push_back(profile->deepCpy()); +} + +/*! + * Creates a new unstructured mesh (MEDCouplingUMesh) from \a this structured one. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If \a this->getMeshDimension() is not among [1,2,3]. + */ +MEDCouplingUMesh *MEDCouplingStructuredMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) +{ + int meshDim=getMeshDimension(); + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),meshDim); + DataArrayDouble *coords=getCoordinatesAndOwner(); + ret->setCoords(coords); + coords->decrRef(); + switch(meshDim) + { + case 1: + fill1DUnstructuredMesh(ret); + break; + case 2: + fill2DUnstructuredMesh(ret); + break; + case 3: + fill3DUnstructuredMesh(ret); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); + }; + return ret; +} + +/*! + * Creates a new MEDCouplingUMesh containing a part of cells of \a this mesh. + * The cells to include to the + * result mesh are specified by an array of cell ids. + * \param [in] start - an array of cell ids to include to the result mesh. + * \param [in] end - specifies the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \return MEDCouplingMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + */ +MEDCouplingMesh *MEDCouplingStructuredMesh::buildPart(const int *start, const int *end) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPart(start,end); + um->decrRef(); + return ret; +} + +MEDCouplingMesh *MEDCouplingStructuredMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); + um->decrRef(); + return ret; +} + +DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::simplexize : not available for Cartesian mesh !"); +} + +/*! + * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this + * 2D mesh. The computed vectors have 3 components and are normalized. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on + * cells and one time. The caller is to delete this field using decrRef() as + * it is no more needed. + * \throw If \a this->getMeshDimension() != 2. + */ +MEDCouplingFieldDouble *MEDCouplingStructuredMesh::buildOrthogonalField() const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("Expected a MEDCouplingStructuredMesh with meshDim == 2 !"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + array->alloc(nbOfCells,3); + double *vals=array->getPointer(); + for(int i=0;isetArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +void MEDCouplingStructuredMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int nbOfCells=-1; + getNodeGridStructure(&nbOfCells); + nbOfCells--; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(nbOfCells+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(3*nbOfCells,1); + ci[0]=0; + int *cp=conn->getPointer(); + for(int i=0;isetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingStructuredMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int ns[2]; + getNodeGridStructure(ns); + int n1=ns[0]-1; + int n2=ns[1]-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(5*n1*n2,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int j=0;jsetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingStructuredMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + int ns[3]; + getNodeGridStructure(ns); + int n1=ns[0]-1; + int n2=ns[1]-1; + int n3=ns[2]-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2*n3+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(9*n1*n2*n3,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int k=0;ksetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +/*! + * Returns a cell id by its (i,j,k) index. The cell is located between the i-th and + * ( i + 1 )-th nodes along X axis etc. + * \param [in] i - a index of node coordinates array along X axis. + * \param [in] j - a index of node coordinates array along Y axis. + * \param [in] k - a index of node coordinates array along Z axis. + * \return int - a cell id in \a this mesh. + */ +int MEDCouplingStructuredMesh::getCellIdFromPos(int i, int j, int k) const +{ + int tmp[3]={i,j,k}; + int tmp2[3]; + int meshDim=getMeshDimension(); + getSplitCellValues(tmp2); + std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); + return std::accumulate(tmp,tmp+meshDim,0); +} + +/*! + * Returns a node id by its (i,j,k) index. + * \param [in] i - a index of node coordinates array along X axis. + * \param [in] j - a index of node coordinates array along Y axis. + * \param [in] k - a index of node coordinates array along Z axis. + * \return int - a node id in \a this mesh. + */ +int MEDCouplingStructuredMesh::getNodeIdFromPos(int i, int j, int k) const +{ + int tmp[3]={i,j,k}; + int tmp2[3]; + int meshDim=getMeshDimension(); + getSplitNodeValues(tmp2); + std::transform(tmp,tmp+meshDim,tmp2,tmp,std::multiplies()); + return std::accumulate(tmp,tmp+meshDim,0); +} + +void MEDCouplingStructuredMesh::GetPosFromId(int nodeId, int meshDim, const int *split, int *res) +{ + int work=nodeId; + for(int i=meshDim-1;i>=0;i--) + { + int pos=work/split[i]; + work=work%split[i]; + res[i]=pos; + } +} diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.hxx b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx new file mode 100644 index 000000000..b04db7add --- /dev/null +++ b/src/MEDCoupling/MEDCouplingStructuredMesh.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Anthony Geay (CEA/DEN) + +#ifndef __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGSTRUCTUREDMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCOUPLING_EXPORT MEDCouplingStructuredMesh : public MEDCouplingMesh + { + public: + INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + std::set getAllGeoTypes() const; + int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); + static void GetPosFromId(int nodeId, int meshDim, const int *split, int *res); + void getNodeIdsOfCell(int cellId, std::vector& conn) const; + std::size_t getHeapMemorySize() const; + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + //tools + std::vector getDistributionOfTypes() const throw(INTERP_KERNEL::Exception); + DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); + void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); + MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildOrthogonalField() const; + void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const; + //some useful methods + int getCellIdFromPos(int i, int j, int k) const; + int getNodeIdFromPos(int i, int j, int k) const; + virtual void getNodeGridStructure(int *res) const = 0; + virtual void getSplitCellValues(int *res) const = 0; + virtual void getSplitNodeValues(int *res) const = 0; + protected: + MEDCouplingStructuredMesh(); + MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy); + ~MEDCouplingStructuredMesh(); + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index 7712aa874..818f4eb71 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,8 +19,9 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingMemArray.hxx" #include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMesh.hxx" #include #include @@ -48,7 +49,7 @@ const char MEDCouplingTwoTimeSteps::EXCEPTION_MSG[]="No data on this time."; const char MEDCouplingLinearTime::REPR[]="Linear time between 2 time steps."; -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type) +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type) throw(INTERP_KERNEL::Exception) { switch(type) { @@ -71,7 +72,7 @@ void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscre _time_unit=other._time_unit; } -void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception) { _time_unit=other._time_unit; if(_array && other._array) @@ -92,7 +93,15 @@ void MEDCouplingTimeDiscretization::updateTime() const updateTimeWith(*_array); } -bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const +std::size_t MEDCouplingTimeDiscretization::getHeapMemorySize() const +{ + std::size_t ret=_time_unit.capacity(); + if(_array) + ret+=_array->getHeapMemorySize(); + return ret; +} + +bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) return false; @@ -105,7 +114,7 @@ bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretiz return true; } -bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception) { std::ostringstream oss; oss.precision(15); if(_time_unit!=other->_time_unit) @@ -134,7 +143,7 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeD return true; } -bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) return false; @@ -147,7 +156,7 @@ bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDi return true; } -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) return false; @@ -163,7 +172,7 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplin return true; } -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) return false; @@ -178,7 +187,7 @@ bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplin return true; } -bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!areStrictlyCompatible(other,reason)) return false; @@ -187,13 +196,13 @@ bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscret return _array->isEqualIfNotWhy(*other->_array,prec,reason); } -bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { std::string reason; return isEqualIfNotWhy(other,prec,reason); } -bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { std::string tmp; if(!areStrictlyCompatible(other,tmp)) @@ -203,7 +212,7 @@ bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCoupli return _array->isEqualWithoutConsideringStr(*other->_array,prec); } -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(type); ret->setTimeUnit(getTimeUnit()); @@ -215,7 +224,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFr return ret; } -void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const +void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { if(_array) { @@ -229,7 +238,7 @@ void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vect } } -void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) +void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) throw(INTERP_KERNEL::Exception) { arrays.resize(1); if(_array!=0) @@ -244,7 +253,7 @@ void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) +void MEDCouplingTimeDiscretization::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception) { _time_tolerance=tinyInfoD[0]; int nbOfCompo=_array->getNumberOfComponents(); @@ -252,12 +261,12 @@ void MEDCouplingTimeDiscretization::finishUnserialization(const std::vector _array->setInfoOnComponent(i,tinyInfoS[i].c_str()); } -void MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const +void MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.push_back(_time_tolerance); } -void MEDCouplingTimeDiscretization::getTinySerializationStrInformation(std::vector& tinyInfo) const +void MEDCouplingTimeDiscretization::getTinySerializationStrInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { int nbOfCompo=_array->getNumberOfComponents(); for(int i=0;idecrRef(); } -void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *owner) +void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception) { if(array!=_array) { @@ -296,17 +305,17 @@ void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel * } } -const DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const +const DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); } -DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() +DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); } -void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) +void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !"); } @@ -318,7 +327,7 @@ void MEDCouplingTimeDiscretization::setArrays(const std::vector& arrays) const +void MEDCouplingTimeDiscretization::getArrays(std::vector& arrays) const throw(INTERP_KERNEL::Exception) { arrays.resize(1); arrays[0]=_array; @@ -347,7 +356,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::doublyContractedPr std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jdoublyContractedProduct(); @@ -355,7 +364,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::doublyContractedPr arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetArrays(arrays3,0); return ret; @@ -366,7 +375,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() cons std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jdeterminant(); @@ -374,7 +383,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() cons arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -387,7 +396,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() cons std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jeigenValues(); @@ -395,7 +404,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() cons arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -408,7 +417,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() con std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jeigenVectors(); @@ -416,7 +425,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() con arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -429,7 +438,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const th std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jinverse(); @@ -437,7 +446,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const th arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -450,7 +459,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const thro std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jtrace(); @@ -458,7 +467,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const thro arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -471,7 +480,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const t std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jdeviator(); @@ -479,7 +488,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const t arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -492,7 +501,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jmagnitude(); @@ -500,7 +509,28 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::negate() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(std::size_t j=0;jnegate(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -513,7 +543,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() cons std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jmaxPerTuple(); @@ -521,7 +551,7 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() cons arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -534,15 +564,15 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedCompon std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jkeepSelectedComponents(compoIds); + arrays2[j]=static_cast(arrays[j]->keepSelectedComponents(compoIds)); else arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); @@ -557,7 +587,7 @@ void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeD other->getArrays(arrays2); if(arrays1.size()!=arrays2.size()) throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !"); - for(unsigned int i=0;isetSelectedComponents(arrays2[i],compoIds); @@ -571,7 +601,7 @@ void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jchangeNbOfComponents(newNbOfComp,dftValue); @@ -579,7 +609,7 @@ void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jsortPerTuple(asc); } } -void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) +void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) throw(INTERP_KERNEL::Exception) { std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;jincrRef(); - arrays[j]->fillWithValue(value); - arrays2[j]=arrays[j]; + arrays2[j]=arrays[j]->changeNbOfComponents(nbOfCompo,value); + arrays2[j]->fillWithValue(value); } else { - DataArrayDouble *tmp=DataArrayDouble::New(); - tmp->alloc(nbOfTuple,nbOfCompo); - tmp->fillWithValue(value); - arrays2[j]=tmp; + arrays2[j]=DataArrayDouble::New(); + arrays2[j]->alloc(nbOfTuple,nbOfCompo); + arrays2[j]->fillWithValue(value); } } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + bool newArr=false; + for(std::size_t j=0;jincrRef(); + arrays2[j]->fillWithValue(value); + } + else + { + newArr=true; + arrays2[j]=DataArrayDouble::New(); + arrays2[j]->alloc(nbOfTuple,1); + arrays2[j]->fillWithValue(value); + } + } + if(newArr) + { + std::vector arrays3(arrays.size()); + for(std::size_t j=0;j arrays; getArrays(arrays); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyLin(a,b,compoId); } } -void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) +void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception) { std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc(nbOfComp,func); @@ -646,17 +704,17 @@ void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate f arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc(nbOfComp,func); @@ -664,17 +722,17 @@ void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const char *func) arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc2(nbOfComp,func); @@ -682,17 +740,17 @@ void MEDCouplingTimeDiscretization::applyFunc2(int nbOfComp, const char *func) arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j& varsOrder, const char *func) +void MEDCouplingTimeDiscretization::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception) { std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); @@ -700,17 +758,17 @@ void MEDCouplingTimeDiscretization::applyFunc3(int nbOfComp, const std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc(func); @@ -718,27 +776,27 @@ void MEDCouplingTimeDiscretization::applyFunc(const char *func) arrays2[j]=0; } std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFuncFast32(func); } } -void MEDCouplingTimeDiscretization::applyFuncFast64(const char *func) +void MEDCouplingTimeDiscretization::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception) { std::vector arrays; getArrays(arrays); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFuncFast64(func); @@ -750,10 +808,10 @@ void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, std::vector arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc(nbOfComp,func); std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc(nbOfComp,func); std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc2(nbOfComp,func); std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j arrays; getArrays(arrays); std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); std::vector arrays3(arrays.size()); - for(int j=0;j<(int)arrays.size();j++) + for(std::size_t j=0;j(other); if(!otherC) @@ -867,7 +930,7 @@ bool MEDCouplingNoTimeLabel::isEqualIfNotWhy(const MEDCouplingTimeDiscretization return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } -bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -875,7 +938,7 @@ bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeD return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -886,7 +949,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCoupli return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector& other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception) { std::vector a(other.size()); int i=0; @@ -903,7 +966,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vect return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -915,7 +978,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTim return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -926,7 +989,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTime return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -937,7 +1000,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCou return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -948,7 +1011,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTime return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -959,7 +1022,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTime return ret; } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -970,7 +1033,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTime return ret; } -void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -980,7 +1043,7 @@ void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other getArray()->addEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -993,7 +1056,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCoupli return ret; } -void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -1003,7 +1066,7 @@ void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization getArray()->substractEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -1014,7 +1077,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplin return ret; } -void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -1024,7 +1087,7 @@ void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization * getArray()->multiplyEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -1035,7 +1098,7 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingT return ret; } -void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) @@ -1045,7 +1108,28 @@ void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *ot getArray()->divideEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::performCpy(bool deepCpy) const +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::powEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::powEqual : Data Array is NULL !"); + getArray()->powEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception) { return new MEDCouplingNoTimeLabel(*this,deepCpy); } @@ -1060,7 +1144,7 @@ std::vector< const DataArrayDouble *> MEDCouplingNoTimeLabel::getArraysForTime(d throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingNoTimeLabel::getValueForTime(double time, const std::vector& vals, double *res) const +void MEDCouplingNoTimeLabel::getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } @@ -1138,7 +1222,7 @@ void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int or /*! * idem getTinySerializationIntInformation except that it is for multi field fetch */ -void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.clear(); } @@ -1146,7 +1230,7 @@ void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingNoTimeLabel::getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(1); tinyInfo[0]=_time_tolerance; @@ -1155,7 +1239,7 @@ void MEDCouplingNoTimeLabel::getTinySerializationDbleInformation2(std::vector& tinyInfoI, const std::vector& tinyInfoD) +void MEDCouplingNoTimeLabel::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception) { _time_tolerance=tinyInfoD[0]; } @@ -1169,7 +1253,7 @@ MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_ord { } -std::string MEDCouplingWithTimeStep::getStringRepr() const +std::string MEDCouplingWithTimeStep::getStringRepr() const throw(INTERP_KERNEL::Exception) { std::ostringstream stream; stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << "."; @@ -1177,20 +1261,31 @@ std::string MEDCouplingWithTimeStep::getStringRepr() const return stream.str(); } -void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const +void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _time=val; _iteration=it; _order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + +void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); tinyInfo.push_back(_iteration); tinyInfo.push_back(_order); } -void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector& tinyInfo) const +void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); tinyInfo.push_back(_time); } -void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) +void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); _time=tinyInfoD[1]; @@ -1201,7 +1296,7 @@ void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tiny /*! * idem getTinySerializationIntInformation except that it is for multi field fetch */ -void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(2); tinyInfo[0]=_iteration; @@ -1211,7 +1306,7 @@ void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingWithTimeStep::getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(2); tinyInfo[0]=_time_tolerance; @@ -1221,7 +1316,7 @@ void MEDCouplingWithTimeStep::getTinySerializationDbleInformation2(std::vector& tinyInfoI, const std::vector& tinyInfoD) +void MEDCouplingWithTimeStep::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception) { _iteration=tinyInfoI[0]; _order=tinyInfoI[1]; @@ -1229,7 +1324,7 @@ void MEDCouplingWithTimeStep::finishUnserialization2(const std::vector& tin _time=tinyInfoD[1]; } -bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatible(other)) return false; @@ -1237,7 +1332,7 @@ bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization return otherC!=0; } -bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; @@ -1248,7 +1343,7 @@ bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscret return ret; } -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) return false; @@ -1256,7 +1351,7 @@ bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeD return otherC!=0; } -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) return false; @@ -1264,7 +1359,7 @@ bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeD return otherC!=0; } -bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) return false; @@ -1272,7 +1367,7 @@ bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscreti return otherC!=0; } -bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); std::ostringstream oss; oss.precision(15); @@ -1302,7 +1397,7 @@ bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretizatio return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } -bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1327,7 +1422,7 @@ void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretizati _order=otherC->_order; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1338,7 +1433,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCoupl return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector& other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception) { std::vector a(other.size()); int i=0; @@ -1355,7 +1450,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vec return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1366,7 +1461,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTi return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1377,7 +1472,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTim return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1388,7 +1483,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCo return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1399,7 +1494,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTim return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1410,7 +1505,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTim return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1424,7 +1519,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTim return ret; } -void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1434,7 +1529,7 @@ void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *othe getArray()->addEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1448,7 +1543,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCoupl return ret; } -void MEDCouplingWithTimeStep::substractEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingWithTimeStep::substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1458,7 +1553,7 @@ void MEDCouplingWithTimeStep::substractEqual(const MEDCouplingTimeDiscretization getArray()->substractEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1472,7 +1567,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCoupli return ret; } -void MEDCouplingWithTimeStep::multiplyEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingWithTimeStep::multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1482,7 +1577,7 @@ void MEDCouplingWithTimeStep::multiplyEqual(const MEDCouplingTimeDiscretization getArray()->multiplyEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1496,7 +1591,7 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCoupling return ret; } -void MEDCouplingWithTimeStep::divideEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingWithTimeStep::divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) @@ -1506,7 +1601,31 @@ void MEDCouplingWithTimeStep::divideEqual(const MEDCouplingTimeDiscretization *o getArray()->divideEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::performCpy(bool deepCpy) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + int tmp1,tmp2; + double tmp3=getStartTime(tmp1,tmp2); + ret->setStartTime(tmp3,tmp1,tmp2); + return ret; +} + +void MEDCouplingWithTimeStep::powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::powEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::powEqual : Data Array is NULL !"); + getArray()->powEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception) { return new MEDCouplingWithTimeStep(*this,deepCpy); } @@ -1538,7 +1657,7 @@ std::vector< const DataArrayDouble *> MEDCouplingWithTimeStep::getArraysForTime( throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingWithTimeStep::getValueForTime(double time, const std::vector& vals, double *res) const +void MEDCouplingWithTimeStep::getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception) { std::copy(vals.begin(),vals.end(),res); } @@ -1583,7 +1702,7 @@ void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscr _end_order=otherC->_end_order; } -void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector& tinyInfo) const +void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); tinyInfo.push_back(_start_iteration); @@ -1592,14 +1711,14 @@ void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vec tinyInfo.push_back(_end_order); } -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector& tinyInfo) const +void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); tinyInfo.push_back(_start_time); tinyInfo.push_back(_end_time); } -void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) +void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); _start_time=tinyInfoD[1]; @@ -1613,7 +1732,7 @@ void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector& tinyInfo) const +void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(4); tinyInfo[0]=_start_iteration; @@ -1625,7 +1744,7 @@ void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation2(std::ve /*! * idem getTinySerializationDbleInformation except that it is for multi field fetch */ -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::vector& tinyInfo) const +void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(3); tinyInfo[0]=_time_tolerance; @@ -1636,7 +1755,7 @@ void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::v /*! * idem finishUnserialization except that it is for multi field fetch */ -void MEDCouplingConstOnTimeInterval::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) +void MEDCouplingConstOnTimeInterval::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception) { _start_iteration=tinyInfoI[0]; _start_order=tinyInfoI[1]; @@ -1653,7 +1772,7 @@ MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval(const MEDCoupling { } -std::string MEDCouplingConstOnTimeInterval::getStringRepr() const +std::string MEDCouplingConstOnTimeInterval::getStringRepr() const throw(INTERP_KERNEL::Exception) { std::ostringstream stream; stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; @@ -1662,7 +1781,19 @@ std::string MEDCouplingConstOnTimeInterval::getStringRepr() const return stream.str(); } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const +void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _start_time=val; _start_iteration=it; _start_order=order; + _end_time=val; _end_iteration=it; _end_order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception) { return new MEDCouplingConstOnTimeInterval(*this,deepCpy); } @@ -1679,12 +1810,12 @@ std::vector< const DataArrayDouble *> MEDCouplingConstOnTimeInterval::getArraysF throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingConstOnTimeInterval::getValueForTime(double time, const std::vector& vals, double *res) const +void MEDCouplingConstOnTimeInterval::getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception) { std::copy(vals.begin(),vals.end(),res); } -bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatible(other)) return false; @@ -1692,7 +1823,7 @@ bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscreti return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; @@ -1703,7 +1834,7 @@ bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTime return ret; } -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) return false; @@ -1711,7 +1842,7 @@ bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCoupli return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) return false; @@ -1719,7 +1850,7 @@ bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCoupli return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) return false; @@ -1727,7 +1858,7 @@ bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeD return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); std::ostringstream oss; oss.precision(15); @@ -1775,7 +1906,7 @@ bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscre return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } -bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1833,7 +1964,7 @@ void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const throw( } } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1844,7 +1975,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const M return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector& other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception) { std::vector a(other.size()); int i=0; @@ -1861,7 +1992,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const s return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1873,7 +2004,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCou return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1884,7 +2015,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCoup return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1895,7 +2026,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(cons return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1906,7 +2037,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCoup return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1917,7 +2048,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCoup return ret; } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1933,7 +2064,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCoup return ret; } -void MEDCouplingConstOnTimeInterval::addEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingConstOnTimeInterval::addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1943,7 +2074,7 @@ void MEDCouplingConstOnTimeInterval::addEqual(const MEDCouplingTimeDiscretizatio getArray()->addEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1959,7 +2090,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const M return ret; } -void MEDCouplingConstOnTimeInterval::substractEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingConstOnTimeInterval::substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1969,7 +2100,7 @@ void MEDCouplingConstOnTimeInterval::substractEqual(const MEDCouplingTimeDiscret getArray()->substractEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1985,7 +2116,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const ME return ret; } -void MEDCouplingConstOnTimeInterval::multiplyEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingConstOnTimeInterval::multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -1995,7 +2126,7 @@ void MEDCouplingConstOnTimeInterval::multiplyEqual(const MEDCouplingTimeDiscreti getArray()->multiplyEqual(other->getArray()); } -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -2011,7 +2142,7 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDC return ret; } -void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) @@ -2021,6 +2152,32 @@ void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretiza getArray()->divideEqual(other->getArray()); } +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + int tmp1,tmp2; + double tmp3=getStartTime(tmp1,tmp2); + ret->setStartTime(tmp3,tmp1,tmp2); + tmp3=getEndTime(tmp1,tmp2); + ret->setEndTime(tmp3,tmp1,tmp2); + return ret; +} + +void MEDCouplingConstOnTimeInterval::powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::powEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::powEqual : Data Array is NULL !"); + getArray()->powEqual(other->getArray()); +} + MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), _start_time(other._start_time),_end_time(other._end_time), _start_iteration(other._start_iteration),_end_iteration(other._end_iteration), @@ -2039,6 +2196,26 @@ void MEDCouplingTwoTimeSteps::updateTime() const updateTimeWith(*_end_array); } +void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _start_time=val; _start_iteration=it; _start_order=order; + _end_time=val; _end_iteration=it; _end_order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + +std::size_t MEDCouplingTwoTimeSteps::getHeapMemorySize() const +{ + std::size_t ret=0; + if(_end_array) + ret+=_end_array->getHeapMemorySize(); + return MEDCouplingTimeDiscretization::getHeapMemorySize()+ret; +} + void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); @@ -2053,7 +2230,7 @@ void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretizati _end_order=otherC->_end_order; } -void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::copyTinyStringsFrom(other); const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(&other); @@ -2063,12 +2240,12 @@ void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretiz _end_array->copyStringInfoFrom(*otherC->_end_array); } -const DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const +const DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const throw(INTERP_KERNEL::Exception) { return _end_array; } -DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() +DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() throw(INTERP_KERNEL::Exception) { return _end_array; } @@ -2084,7 +2261,7 @@ void MEDCouplingTwoTimeSteps::checkCoherency() const throw(INTERP_KERNEL::Except throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !"); } -bool MEDCouplingTwoTimeSteps::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +bool MEDCouplingTwoTimeSteps::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) { std::ostringstream oss; const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); @@ -2138,7 +2315,7 @@ bool MEDCouplingTwoTimeSteps::isEqualIfNotWhy(const MEDCouplingTimeDiscretizatio return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); } -bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception) { const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); if(!otherC) @@ -2187,14 +2364,14 @@ void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const throw(INTERP_ } } -void MEDCouplingTwoTimeSteps::getArrays(std::vector& arrays) const +void MEDCouplingTwoTimeSteps::getArrays(std::vector& arrays) const throw(INTERP_KERNEL::Exception) { arrays.resize(2); arrays[0]=_array; arrays[1]=_end_array; } -void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) +void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception) { if(array!=_end_array) { @@ -2208,7 +2385,7 @@ void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *own } } -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const +void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); tinyInfo.push_back(_start_iteration); @@ -2227,14 +2404,14 @@ void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const +void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); tinyInfo.push_back(_start_time); tinyInfo.push_back(_end_time); } -void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const +void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { int nbOfCompo=_array->getNumberOfComponents(); for(int i=0;igetInfoOnComponent(i)); } -void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) +void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) throw(INTERP_KERNEL::Exception) { arrays.resize(2); if(_array!=0) @@ -2268,7 +2445,7 @@ void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& t arrays[1]=arr; } -void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) +void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception) { MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); _start_time=tinyInfoD[1]; @@ -2282,7 +2459,7 @@ void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tiny /*! * idem getTinySerializationIntInformation except that it is for multi field fetch */ -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(4); tinyInfo[0]=_start_iteration; @@ -2294,7 +2471,7 @@ void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector& tinyInfo) const +void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) { tinyInfo.resize(3); tinyInfo[0]=_time_tolerance; @@ -2305,7 +2482,7 @@ void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation2(std::vector& tinyInfoI, const std::vector& tinyInfoD) +void MEDCouplingTwoTimeSteps::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception) { _start_iteration=tinyInfoI[0]; _start_order=tinyInfoI[1]; @@ -2345,7 +2522,7 @@ MEDCouplingLinearTime::MEDCouplingLinearTime() { } -std::string MEDCouplingLinearTime::getStringRepr() const +std::string MEDCouplingLinearTime::getStringRepr() const throw(INTERP_KERNEL::Exception) { std::ostringstream stream; stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; @@ -2361,12 +2538,12 @@ void MEDCouplingLinearTime::checkCoherency() const throw(INTERP_KERNEL::Exceptio throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance."); } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception) { return new MEDCouplingLinearTime(*this,deepCpy); } -bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatible(other)) return false; @@ -2382,7 +2559,7 @@ bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *o return true; } -bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) return false; @@ -2393,7 +2570,7 @@ bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretiz return ret; } -bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) return false; @@ -2401,7 +2578,7 @@ bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDis return otherC!=0; } -bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) return false; @@ -2419,7 +2596,7 @@ bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDis return true; } -bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) return false; @@ -2430,7 +2607,7 @@ bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretiza /*! * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples() */ -void MEDCouplingLinearTime::getValueForTime(double time, const std::vector& vals, double *res) const +void MEDCouplingLinearTime::getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception) { double alpha=(_end_time-time)/(_end_time-_start_time); std::size_t nbComp=vals.size()/2; @@ -2479,7 +2656,7 @@ void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int ord throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2492,7 +2669,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplin return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector& other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception) { std::vector a(other.size()); std::vector b(other.size()); @@ -2513,7 +2690,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vecto return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2527,7 +2704,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTime return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2540,7 +2717,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeD return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2553,7 +2730,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCoup return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2566,7 +2743,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeD return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2579,7 +2756,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeD return ret; } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2592,7 +2769,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeD return ret; } -void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2605,7 +2782,7 @@ void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) getEndArray()->addEqual(other->getEndArray()); } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2618,7 +2795,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplin return ret; } -void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2631,7 +2808,7 @@ void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization * getEndArray()->substractEqual(other->getEndArray()); } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2644,7 +2821,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCoupling return ret; } -void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2657,7 +2834,7 @@ void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *o getEndArray()->multiplyEqual(other->getEndArray()); } -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2670,7 +2847,7 @@ MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTi return ret; } -void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) +void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) { const MEDCouplingLinearTime *otherC=dynamic_cast(other); if(!otherC) @@ -2682,3 +2859,29 @@ void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *oth getArray()->divideEqual(other->getArray()); getEndArray()->divideEqual(other->getEndArray()); } + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Pow(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +void MEDCouplingLinearTime::powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::powEqual : Data Array is NULL !"); + if(!getEndArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::powEqual : Data Array (end) is NULL !"); + getArray()->powEqual(other->getArray()); + getEndArray()->powEqual(other->getEndArray()); +} diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index 79d6fa07a..8cdbbe957 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,7 @@ namespace ParaMEDMEM { + class MEDCouplingMesh; class DataArrayDouble; class TimeLabel; @@ -40,61 +41,65 @@ namespace ParaMEDMEM MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy); public: void updateTime() const; - static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); + virtual std::size_t getHeapMemorySize() const; + static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type) throw(INTERP_KERNEL::Exception); void setTimeUnit(const char *unit) { _time_unit=unit; } const char *getTimeUnit() const { return _time_unit.c_str(); } virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); + virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; - virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; - virtual std::string getStringRepr() const = 0; - virtual TypeOfTimeDiscretization getEnum() const = 0; - virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const = 0; - virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0; - virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0; - virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0; - virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0; - virtual void substractEqual(const MEDCouplingTimeDiscretization *other) = 0; - virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const = 0; - virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) = 0; - virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const = 0; - virtual void divideEqual(const MEDCouplingTimeDiscretization *other) = 0; - virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; - virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - virtual void getTinySerializationStrInformation(std::vector& tinyInfo) const; - virtual void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - virtual void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - virtual void getTinySerializationIntInformation2(std::vector& tinyInfo) const = 0; - virtual void getTinySerializationDbleInformation2(std::vector& tinyInfo) const = 0; - virtual void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) = 0; - virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const = 0; + virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); + virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const throw(INTERP_KERNEL::Exception); + virtual std::string getStringRepr() const throw(INTERP_KERNEL::Exception) = 0; + virtual TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception) = 0; + virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception) = 0; + virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + virtual void getTinySerializationStrInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + virtual void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) throw(INTERP_KERNEL::Exception); + virtual void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception); + virtual void getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) = 0; + virtual void getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception) = 0; + virtual void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception) = 0; + virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception) = 0; void setTimeTolerance(double val) { _time_tolerance=val; } double getTimeTolerance() const { return _time_tolerance; } virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) = 0; virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception) = 0; - virtual void setArray(DataArrayDouble *array, TimeLabel *owner); - virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner); + virtual void setArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception); + virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception); virtual void setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getArray() { return _array; } - const DataArrayDouble *getArray() const { return _array; } - virtual const DataArrayDouble *getEndArray() const; - virtual DataArrayDouble *getEndArray(); + DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception) { return _array; } + const DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception) { return _array; } + virtual const DataArrayDouble *getEndArray() const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception); virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception) = 0; - virtual void getValueForTime(double time, const std::vector& vals, double *res) const = 0; - virtual void getArrays(std::vector& arrays) const; + virtual void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception) = 0; + virtual void getArrays(std::vector& arrays) const throw(INTERP_KERNEL::Exception); virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); double getTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { return getStartTime(iteration,order); } @@ -123,20 +128,22 @@ namespace ParaMEDMEM virtual MEDCouplingTimeDiscretization *trace() const throw(INTERP_KERNEL::Exception); virtual MEDCouplingTimeDiscretization *deviator() const throw(INTERP_KERNEL::Exception); virtual MEDCouplingTimeDiscretization *magnitude() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *negate() const throw(INTERP_KERNEL::Exception); virtual MEDCouplingTimeDiscretization *maxPerTuple() const throw(INTERP_KERNEL::Exception); virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); virtual void changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception); virtual void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value); - virtual void applyLin(double a, double b, int compoId); - virtual void applyFunc(int nbOfComp, FunctionToEvaluate func); - virtual void applyFunc(int nbOfComp, const char *func); - virtual void applyFunc2(int nbOfComp, const char *func); - virtual void applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func); - virtual void applyFunc(const char *func); - virtual void applyFuncFast32(const char *func); - virtual void applyFuncFast64(const char *func); + virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value) throw(INTERP_KERNEL::Exception); + virtual void setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value) throw(INTERP_KERNEL::Exception); + virtual void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); + virtual void applyFunc(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); + virtual void applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); + virtual void applyFunc2(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); + virtual void applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception); + virtual void applyFunc(const char *func) throw(INTERP_KERNEL::Exception); + virtual void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception); + virtual void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception); virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); virtual void fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); @@ -156,35 +163,38 @@ namespace ParaMEDMEM public: MEDCouplingNoTimeLabel(); MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); - std::string getStringRepr() const; - TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - void divideEqual(const MEDCouplingTimeDiscretization *other); - bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + std::string getStringRepr() const throw(INTERP_KERNEL::Exception); + TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception) { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); + bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) { } void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); - void getValueForTime(double time, const std::vector& vals, double *res) const; + void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); @@ -199,9 +209,9 @@ namespace ParaMEDMEM void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); - void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); + void getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception); public: static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; static const char REPR[]; @@ -215,38 +225,41 @@ namespace ParaMEDMEM MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy); public: MEDCouplingWithTimeStep(); - std::string getStringRepr() const; + std::string getStringRepr() const throw(INTERP_KERNEL::Exception); void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - void divideEqual(const MEDCouplingTimeDiscretization *other); - bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - void getTinySerializationIntInformation(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception) { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); + bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception); + void getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _time=time; _iteration=iteration; _order=order; } @@ -260,7 +273,7 @@ namespace ParaMEDMEM void setStartTimeValue(double time) throw(INTERP_KERNEL::Exception) { _time=time; } void setEndTimeValue(double time) throw(INTERP_KERNEL::Exception) { _time=time; } std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); - void getValueForTime(double time, const std::vector& vals, double *res) const; + void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); public: @@ -281,41 +294,44 @@ namespace ParaMEDMEM public: MEDCouplingConstOnTimeInterval(); void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - void getTinySerializationIntInformation(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + void getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception); + void getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); - void getValueForTime(double time, const std::vector& vals, double *res) const; + void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); - TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - std::string getStringRepr() const; - MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - void divideEqual(const MEDCouplingTimeDiscretization *other); + TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception) { return DISCRETIZATION; } + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + std::string getStringRepr() const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; } void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; } double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; } @@ -350,17 +366,19 @@ namespace ParaMEDMEM ~MEDCouplingTwoTimeSteps(); public: void updateTime() const; + void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + std::size_t getHeapMemorySize() const; void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); - const DataArrayDouble *getEndArray() const; - DataArrayDouble *getEndArray(); + void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); + const DataArrayDouble *getEndArray() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception); void checkCoherency() const throw(INTERP_KERNEL::Exception); - bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const throw(INTERP_KERNEL::Exception); void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); - void getArrays(std::vector& arrays) const; - void setEndArray(DataArrayDouble *array, TimeLabel *owner); + void getArrays(std::vector& arrays) const throw(INTERP_KERNEL::Exception); + void setEndArray(DataArrayDouble *array, TimeLabel *owner) throw(INTERP_KERNEL::Exception); void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; } void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; } double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; } @@ -371,14 +389,14 @@ namespace ParaMEDMEM void setEndOrder(int order) throw(INTERP_KERNEL::Exception) { _end_order=order; } void setStartTimeValue(double time) throw(INTERP_KERNEL::Exception) { _start_time=time; } void setEndTimeValue(double time) throw(INTERP_KERNEL::Exception) { _end_time=time; } - void getTinySerializationIntInformation(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - void getTinySerializationStrInformation(std::vector& tinyInfo) const; - void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); + void getTinySerializationIntInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationStrInformation(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) throw(INTERP_KERNEL::Exception); + void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) throw(INTERP_KERNEL::Exception); + void getTinySerializationIntInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void getTinySerializationDbleInformation2(std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); + void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) throw(INTERP_KERNEL::Exception); std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); void setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); protected: @@ -399,33 +417,35 @@ namespace ParaMEDMEM MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy); public: MEDCouplingLinearTime(); - std::string getStringRepr() const; - TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + std::string getStringRepr() const throw(INTERP_KERNEL::Exception); + TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception) { return DISCRETIZATION; } void checkCoherency() const throw(INTERP_KERNEL::Exception); - MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - void getValueForTime(double time, const std::vector& vals, double *res) const; + MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + bool areCompatible(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); - MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - void divideEqual(const MEDCouplingTimeDiscretization *other); + MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); public: static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; static const char REPR[]; diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/src/MEDCoupling/MEDCouplingTimeLabel.cxx index 9c2716c1e..85c1d33f0 100644 --- a/src/MEDCoupling/MEDCouplingTimeLabel.cxx +++ b/src/MEDCoupling/MEDCouplingTimeLabel.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -48,3 +48,12 @@ void TimeLabel::updateTimeWith(const TimeLabel& other) const if(_timegetHeapMemorySize(); + if(_nodal_connec_index) + ret+=_nodal_connec_index->getHeapMemorySize(); + return MEDCouplingPointSet::getHeapMemorySize()+ret; +} + void MEDCouplingUMesh::updateTime() const { MEDCouplingPointSet::updateTime(); @@ -88,21 +111,29 @@ void MEDCouplingUMesh::updateTime() const } } -MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2), - _nodal_connec(0),_nodal_connec_index(0) +MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0) { } /*! - * This method checks that this is correctly designed. For example le coordinates are set, nodal connectivity. - * When this method returns without throwing any exception, 'this' is expected to be writable, exchangeable and to be - * available for most of algorithm. When a mesh has been constructed from scratch it is a good habits to call this method to check - * that all is in order in 'this'. + * Checks if \a this mesh is well defined. If no exception is thrown by this method, + * then \a this mesh is most probably is writable, exchangeable and available for most + * of algorithms. When a mesh is constructed from scratch, it is a good habit to call + * this method to check that all is in order with \a this mesh. + * \throw If the mesh dimension is not set. + * \throw If the coordinates array is not set (if mesh dimension != -1 ). + * \throw If \a this mesh contains elements of dimension different from the mesh dimension. + * \throw If the connectivity data array has more than one component. + * \throw If the connectivity data array has a named component. + * \throw If the connectivity index data array has more than one component. + * \throw If the connectivity index data array has a named component. */ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) { if(_mesh_dim<-1) - throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + if(_mesh_dim!=-1) + MEDCouplingPointSet::checkCoherency(); for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) { if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim) @@ -126,16 +157,23 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec_index->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); } - if(_iterator!=-1) - { - throw INTERP_KERNEL::Exception("It appears that finishInsertingCells method has not been invoked after a insertNextCell session !"); - } } /*! - * 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. + * Checks if \a this mesh is well defined. If no exception is thrown by this method, + * then \a this mesh is most probably is writable, exchangeable and available for all + * algorithms.
In addition to the checks performed by checkCoherency(), this + * method thoroughly checks the nodal connectivity. + * \param [in] eps - a not used parameter. + * \throw If the mesh dimension is not set. + * \throw If the coordinates array is not set (if mesh dimension != -1 ). + * \throw If \a this mesh contains elements of dimension different from the mesh dimension. + * \throw If the connectivity data array has more than one component. + * \throw If the connectivity data array has a named component. + * \throw If the connectivity index data array has more than one component. + * \throw If the connectivity index data array has a named component. + * \throw If number of nodes defining an element does not correspond to the type of element. + * \throw If the nodal connectivity includes an invalid node id. */ void MEDCouplingUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception) { @@ -193,19 +231,49 @@ void MEDCouplingUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Ex } } + +/*! + * Checks if \a this mesh is well defined. If no exception is thrown by this method, + * then \a this mesh is most probably is writable, exchangeable and available for all + * algorithms.
This method performs the same checks as checkCoherency1() does. + * \param [in] eps - a not used parameter. + * \throw If the mesh dimension is not set. + * \throw If the coordinates array is not set (if mesh dimension != -1 ). + * \throw If \a this mesh contains elements of dimension different from the mesh dimension. + * \throw If the connectivity data array has more than one component. + * \throw If the connectivity data array has a named component. + * \throw If the connectivity index data array has more than one component. + * \throw If the connectivity index data array has a named component. + * \throw If number of nodes defining an element does not correspond to the type of element. + * \throw If the nodal connectivity includes an invalid node id. + */ void MEDCouplingUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception) { checkCoherency1(eps); } +/*! + * Sets dimension of \a this mesh. The mesh dimension in general depends on types of + * elements contained in the mesh. For more info on the mesh dimension see + * \ref MEDCouplingUMeshPage. + * \param [in] meshDim - a new mesh dimension. + * \throw If \a meshDim is invalid. A valid range is -1 <= meshDim <= 3. + */ void MEDCouplingUMesh::setMeshDimension(int meshDim) { - if(meshDim<-1) - throw INTERP_KERNEL::Exception("Invalid meshDim specified ! Must be greater or equal to -1 !"); + if(meshDim<-1 || meshDim>3) + throw INTERP_KERNEL::Exception("Invalid meshDim specified ! Must be greater or equal to -1 and lower or equal to 3 !"); _mesh_dim=meshDim; declareAsNew(); } +/*! + * Allocates memory to store given number of cells. + * \param [in] nbOfCells - number of cell \a this mesh will contain. + * + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + */ void MEDCouplingUMesh::allocateCells(int nbOfCells) { if(_nodal_connec_index) @@ -216,23 +284,24 @@ void MEDCouplingUMesh::allocateCells(int nbOfCells) { _nodal_connec->decrRef(); } - _nodal_connec_index=DataArrayInt::New(); - _nodal_connec_index->alloc(nbOfCells+1,1); - int *pt=_nodal_connec_index->getPointer(); - pt[0]=0; + _nodal_connec_index->reserve(nbOfCells+1); + _nodal_connec_index->pushBackSilent(0); _nodal_connec=DataArrayInt::New(); - _nodal_connec->alloc(2*nbOfCells,1); - _iterator=0; + _nodal_connec->reserve(2*nbOfCells); _types.clear(); declareAsNew(); } /*! - * Appends a cell in connectivity array. - * @param type type of cell to add. - * @param size number of nodes constituting this cell. - * @param nodalConnOfCell the connectivity of the cell to add. + * Appends a cell to the connectivity array. For deeper understanding what is + * happening see \ref MEDCouplingUMeshNodalConnectivity. + * \param [in] type - type of cell to add. + * \param [in] size - number of nodes constituting this cell. + * \param [in] nodalConnOfCell - the connectivity of the cell to add. + * + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". */ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) throw(INTERP_KERNEL::Exception) { @@ -241,15 +310,18 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !"); if((int)cm.getDimension()==_mesh_dim) { - int nbOfElems=_nodal_connec_index->getNbOfElems()-1; - if(_iterator>=nbOfElems) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : allocation of cells was wide enough ! Call insertNextCell with higher value or call finishInsertingCells !"); - int *pt=_nodal_connec_index->getPointer(); - int idx=pt[_iterator]; - + if(!cm.isDynamic()) + if(size!=(int)cm.getNumberOfNodes()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : Trying to push a " << cm.getRepr() << " cell with a size of " << size; + oss << " ! Expecting " << cm.getNumberOfNodes() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int idx=_nodal_connec_index->back(); + int val=idx+size+1; + _nodal_connec_index->pushBackSilent(val); _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size); _types.insert(type); - pt[++_iterator]=idx+size+1; } else { @@ -261,16 +333,16 @@ void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, in } /*! - * Method to be called to cloture the insertion of cells using this->insertNextCell. + * Compacts data arrays to release unused memory. This method is to be called after + * finishing cell insertion using \a this->insertNextCell(). + * + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
+ * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". */ void MEDCouplingUMesh::finishInsertingCells() { - const int *pt=_nodal_connec_index->getConstPointer(); - int idx=pt[_iterator]; - - _nodal_connec->reAlloc(idx); - _nodal_connec_index->reAlloc(_iterator+1); - _iterator=-1; + _nodal_connec->pack(); + _nodal_connec_index->pack(); _nodal_connec->declareAsNew(); _nodal_connec_index->declareAsNew(); updateTime(); @@ -298,6 +370,10 @@ MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() throw(INTERP_KE return new MEDCouplingUMeshCellByTypeEntry(this); } +/*! + * Returns a set of all cell types available in \a this mesh. + * \return std::set - the set of cell types. + */ std::set MEDCouplingUMesh::getAllGeoTypes() const { return _types; @@ -364,6 +440,14 @@ bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec return true; } +/*! + * Checks if data arrays of this mesh (node coordinates, nodal + * connectivity of cells, etc) of two meshes are same. Textual data like name etc. are + * not considered. + * \param [in] other - the mesh to compare with. + * \param [in] prec - precision value used to compare node coordinates. + * \return bool - \a true if the two meshes are same. + */ bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const { const MEDCouplingUMesh *otherC=dynamic_cast(other); @@ -391,13 +475,24 @@ bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other } /*! - * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one - * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. - * - * In case of success cellCor and nodeCor are informed both. - * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method. - * @param cellCor output array giving the correspondance of cells from 'other' to 'this'. - * @param nodeCor output array giving the correspondance of nodes from 'other' to 'this'. + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are + * considered equivalent if (1) \a this mesh contains the same nodes as the \a other + * mesh (with a specified precision) and (2) \a this mesh contains the same cells as + * the \a other mesh (with use of a specified cell comparison technique). The mapping + * from \a other to \a this for nodes and cells is returned via out parameters. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of + * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). + * \param [in] prec - the precision used to compare nodes of the two meshes. + * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + * + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
+ * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". */ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) @@ -426,28 +521,34 @@ void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int ce // da=m->zipConnectivityTraducer(cellCompPol); - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); - pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + int nbCells=getNumberOfCells(); + int maxId=-1; + if(nbCells!=0) + maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+nbCells); + pt=std::find_if(da->getConstPointer()+nbCells,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); if(pt!=da->getConstPointer()+da->getNbOfElems()) throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - MEDCouplingAutoRefCountObjectPtr cellCor2=DataArrayInt::New(); - cellCor2->alloc(otherC->getNumberOfCells(),1); - std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer()); - bool nident=nodeCor2->isIdentity(); - bool cident=cellCor2->isIdentity(); - if(!nident) { nodeCor=nodeCor2; nodeCor2->incrRef(); } else nodeCor=0; - if(!cident) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0; -} - -/*! - * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one - * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. The difference with MEDCouplingUMesh::checkDeepEquivalWith method is that - * coordinates of 'this' and 'other' are expected to be the same. If not an exception will be thrown. - * This method is close to MEDCouplingUMesh::areCellsIncludedIn except that this method throws exception ! - * - * In case of success cellCor are informed both. - * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method. - * @param cellCor output array giving the correspondance of cells from 'other' to 'this'. + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1); + nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); +} + +/*! + * Checks if \a this and \a other meshes are geometrically equivalent, else an + * exception is thrown. The meshes are considered equivalent if (1) they share one + * node coordinates array and (2) they contain the same cells (with use of a specified + * cell comparison technique). The mapping from cells of the \a other to ones of \a this + * is returned via an out parameter. + * \param [in] other - the mesh to compare with. + * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of + * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). + * \param [in] prec - a not used parameter. + * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is + * to delete this array using decrRef() as it is no more needed. + * \throw If the two meshes do not match. + * + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
+ * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". */ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) @@ -471,14 +572,19 @@ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot { throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); } - MEDCouplingAutoRefCountObjectPtr cellCor2=DataArrayInt::New(); - cellCor2->alloc(otherC->getNumberOfCells(),1); - std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer()); - if(!cellCor2->isIdentity()) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0; + MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); } /*! - * This method checks fastly that 'this' and 'other' are equal. + * Checks if \a this and \a other meshes are geometrically equivalent with high + * probability, else an exception is thrown. The meshes are considered equivalent if + * (1) meshes contain the same number of nodes and the same number of elements of the + * same types (2) three cells of the two meshes (first, last and middle) are based + * on coincident nodes (with a specified precision). + * \param [in] other - the mesh to compare with. + * \param [in] prec - the precision used to compare nodes of the two meshes. + * \throw If the two meshes do not match. */ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { @@ -498,15 +604,32 @@ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double } /*! - * \b WARNING this method do the assumption that connectivity lies on the coordinates set. - * For speed reasons no check of this will be done. + * Returns the reverse nodal connectivity. The reverse nodal connectivity enumerates + * cells each node belongs to. + * \warning For speed reasons, this method does not check if node ids in the nodal + * connectivity correspond to the size of node coordinates array. + * \param [in,out] revNodal - an array holding ids of cells sharing each node. + * \param [in,out] revNodalIndx - an array, of length \a this->getNumberOfNodes() + 1, + * dividing cell ids in \a revNodal into groups each referring to one + * node. Its every element (except the last one) is an index pointing to the + * first id of a group of cells. For example cells sharing the node #1 are + * described by following range of indices: + * [ \a revNodalIndx[1], \a revNodalIndx[2] ) and the cell ids are + * \a revNodal[ \a revNodalIndx[1] ], \a revNodal[ \a revNodalIndx[1] + 1], ... + * Number of cells sharing the *i*-th node is + * \a revNodalIndx[ *i*+1 ] - \a revNodalIndx[ *i* ]. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".
+ * \ref py_mcumesh_getReverseNodalConnectivity "Here is a Python example". */ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception) { checkFullyDefined(); int nbOfNodes=getNumberOfNodes(); - int *revNodalIndxPtr=new int[nbOfNodes+1]; - revNodalIndx->useArray(revNodalIndxPtr,true,CPP_DEALLOC,nbOfNodes+1,1); + int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int)); + revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1); std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0); const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); @@ -524,8 +647,8 @@ void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataA } } std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); - int *revNodalPtr=new int[nbOfEltsInRevNodal]; - revNodal->useArray(revNodalPtr,true,CPP_DEALLOC,nbOfEltsInRevNodal,1); + int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int)); + revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1); std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1); for(int eltId=0;eltIdgetMeshDimension(), that bound cells of \a this mesh. In addition arrays + * describing correspondence between cells of \a this and the result meshes are + * returned. The arrays \a desc and \a descIndx describe the descending connectivity, + * i.e. enumerate cells of the result mesh bounding each cell of \a this mesh. The + * arrays \a revDesc and \a revDescIndx describe the reverse descending connectivity, + * i.e. enumerate cells of \a this mesh bounded by each cell of the result mesh. + * \warning For speed reasons, this method does not check if node ids in the nodal + * connectivity correspond to the size of node coordinates array. + * \warning Cells of the result mesh are \b not sorted by geometric type, hence, + * to write this mesh to the MED file, its cells must be sorted using + * sortCellsInMEDFileFrmt(). + * \param [in,out] desc - the array containing cell ids of the result mesh bounding + * each cell of \a this mesh. + * \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1, + * dividing cell ids in \a desc into groups each referring to one + * cell of \a this mesh. Its every element (except the last one) is an index + * pointing to the first id of a group of cells. For example cells of the + * result mesh bounding the cell #1 of \a this mesh are described by following + * range of indices: + * [ \a descIndx[1], \a descIndx[2] ) and the cell ids are + * \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ... + * Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is + * \a descIndx[ *i*+1 ] - \a descIndx[ *i* ]. + * \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded + * by each cell of the result mesh. + * \param [in,out] revDescIndx - the array, of length one more than number of cells + * in the result mesh, + * dividing cell ids in \a revDesc into groups each referring to one + * cell of the result mesh the same way as \a descIndx divides \a desc. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is node defined. + * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a + * revDescIndx == NULL. + * + * \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".
+ * \ref py_mcumesh_buildDescendingConnectivity "Here is a Python example". + * \sa buildDescendingConnectivity2() */ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception) { - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); + return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); } /*! - * WARNING this method do the assumption that connectivity lies on the coordinates set. - * For speed reasons no check of this will be done. - * This method differs from MEDCouplingUMesh::buildDescendingConnectivity method in that 'desc' is in different format. - * This method is more precise because it returns in descending connectivity giving the direction. If value is positive the n-1 dim element is taken in the same direction, - * if it is in the opposite direction it is retrieved negative. So the problem is for elemt #0 in C convention. That's why this method is the only one that retrieves - * an array in relative "FORTRAN" mode. - * - * \warning This method returns a mesh whose geometric type order in are \b not sorted. - * In view of the MED file writing, a renumbering of cells in returned mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. + * \a this has to have a mesh dimension equal to 3. If it is not the case an INTERP_KERNEL::Exception will be thrown. + * This behaves exactly as MEDCouplingUMesh::buildDescendingConnectivity does except that this method compute directly the transition from mesh dimension 3 to sub edges (dimension 1) + * in one shot. That is to say that this method is equivalent to 2 successive calls to MEDCouplingUMesh::buildDescendingConnectivity. + * This method returns 4 arrays and a mesh as MEDCouplingUMesh::buildDescendingConnectivity does. + * \sa MEDCouplingUMesh::buildDescendingConnectivity + */ +MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception) +{ + checkFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::explode3DMeshTo1D : This has to have a mesh dimension to 3 !"); + return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); +} + +/*! + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a + * this->getMeshDimension(), that bound cells of \a this mesh. In + * addition arrays describing correspondence between cells of \a this and the result + * meshes are returned. The arrays \a desc and \a descIndx describe the descending + * connectivity, i.e. enumerate cells of the result mesh bounding each cell of \a this + * mesh. This method differs from buildDescendingConnectivity() in that apart + * from cell ids, \a desc returns mutual orientation of cells in \a this and the + * result meshes. So a positive id means that order of nodes in corresponding cells + * of two meshes is same, and a negative id means a reverse order of nodes. Since a + * cell with id #0 can't be negative, the array \a desc returns ids in FORTRAN mode, + * i.e. cell ids are one-based. + * Arrays \a revDesc and \a revDescIndx describe the reverse descending connectivity, + * i.e. enumerate cells of \a this mesh bounded by each cell of the result mesh. + * \warning For speed reasons, this method does not check if node ids in the nodal + * connectivity correspond to the size of node coordinates array. + * \warning Cells of the result mesh are \b not sorted by geometric type, hence, + * to write this mesh to the MED file, its cells must be sorted using + * sortCellsInMEDFileFrmt(). + * \param [in,out] desc - the array containing cell ids of the result mesh bounding + * each cell of \a this mesh. + * \param [in,out] descIndx - the array, of length \a this->getNumberOfCells() + 1, + * dividing cell ids in \a desc into groups each referring to one + * cell of \a this mesh. Its every element (except the last one) is an index + * pointing to the first id of a group of cells. For example cells of the + * result mesh bounding the cell #1 of \a this mesh are described by following + * range of indices: + * [ \a descIndx[1], \a descIndx[2] ) and the cell ids are + * \a desc[ \a descIndx[1] ], \a desc[ \a descIndx[1] + 1], ... + * Number of cells of the result mesh sharing the *i*-th cell of \a this mesh is + * \a descIndx[ *i*+1 ] - \a descIndx[ *i* ]. + * \param [in,out] revDesc - the array containing cell ids of \a this mesh bounded + * by each cell of the result mesh. + * \param [in,out] revDescIndx - the array, of length one more than number of cells + * in the result mesh, + * dividing cell ids in \a revDesc into groups each referring to one + * cell of the result mesh the same way as \a descIndx divides \a desc. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This result mesh + * shares the node coordinates array with \a this mesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is node defined. + * \throw If \a desc == NULL || \a descIndx == NULL || \a revDesc == NULL || \a + * revDescIndx == NULL. + * + * \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".
+ * \ref py_mcumesh_buildDescendingConnectivity2 "Here is a Python example". + * \sa buildDescendingConnectivity() */ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception) { - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer); + return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer); } /*! @@ -651,22 +883,19 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons MEDCouplingAutoRefCountObjectPtr out1=DataArrayInt::New(); out1->alloc(nbCells+1,1); int *out1Ptr=out1->getPointer(); *out1Ptr++=0; - std::vector out0v; - out0v.reserve(desc->getNumberOfTuples()); + out0->reserve(desc->getNumberOfTuples()); for(int i=0;i s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]); s.erase(i); - out0v.insert(out0v.end(),s.begin(),s.end()); + out0->insertAtTheEnd(s.begin(),s.end()); } - *out1Ptr=out0v.size(); + *out1Ptr=out0->getNumberOfTuples(); } - out0->alloc((int)out0v.size(),1); - std::copy(out0v.begin(),out0v.end(),out0->getPointer()); - neighbors=out0; out0->incrRef(); - neighborsIndx=out1; out1->incrRef(); + neighbors=out0.retn(); + neighborsIndx=out1.retn(); } /// @cond INTERNAL @@ -675,105 +904,117 @@ void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, cons * \b WARNING this method do the assumption that connectivity lies on the coordinates set. * For speed reasons no check of this will be done. */ +template MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception) { + if(!desc || !descIndx || !revDesc || !revDescIndx) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !"); checkConnectivityFullyDefined(); int nbOfCells=getNumberOfCells(); int nbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr revNodalIndx=DataArrayInt::New(); revNodalIndx->alloc(nbOfNodes+1,1); revNodalIndx->fillWithZero(); + int *revNodalIndxPtr=revNodalIndx->getPointer(); const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); - std::vector< std::vector > descMeshConnB(nbOfCells); - std::vector< std::vector > revDescMeshConnB; - std::vector< std::vector > revNodalB(nbOfNodes); - std::vector meshDM1Conn; - std::vector meshDM1ConnIndex(1); meshDM1ConnIndex[0]=0; - std::vector meshDM1Type; - for(int eltId=0;eltId ret=MEDCouplingUMesh::New(name.c_str(),getMeshDimension()-SonsGenerator::DELTA); + ret->setCoords(getCoords()); + ret->allocateCells(2*nbOfCells); + descIndx->alloc(nbOfCells+1,1); + MEDCouplingAutoRefCountObjectPtr revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells); + int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0; + for(int eltId=0;eltId tmp=new int[posP1-pos]; for(unsigned i=0;i shareableCells(revNodalB[tmp[0]].begin(),revNodalB[tmp[0]].end()); - for(unsigned j=1;j tmp2(revNodalB[tmp[j]].begin(),revNodalB[tmp[j]].end()); - std::set tmp3; - std::set_intersection(tmp2.begin(),tmp2.end(),shareableCells.begin(),shareableCells.end(),inserter(tmp3,tmp3.begin())); - shareableCells=tmp3; - } - std::list shareableCellsL(shareableCells.begin(),shareableCells.end()); - std::set ref(tmp,tmp+nbOfNodesSon); - for(std::list::iterator iter=shareableCellsL.begin();iter!=shareableCellsL.end();) - { - if(cms.isCompatibleWith((INTERP_KERNEL::NormalizedCellType)meshDM1Type[*iter])) - { - std::set ref2(meshDM1Conn.begin()+meshDM1ConnIndex[*iter],meshDM1Conn.begin()+meshDM1ConnIndex[(*iter)+1]); - if(ref==ref2) - break; - else - iter=shareableCellsL.erase(iter); - } - else - iter=shareableCellsL.erase(iter); - } - if(shareableCellsL.empty()) + unsigned nbOfNodesSon=sg.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId); + for(unsigned k=0;k=0) + revNodalIndxPtr[tmp[k]+1]++; + ret->insertNextCell(cmsId,nbOfNodesSon,tmp); + revDesc2->pushBackSilent(eltId); + } + descIndxPtr[0]=descIndxPtr[-1]+(int)nbOfSons; + } + int nbOfCellsM1=ret->getNumberOfCells(); + std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); + MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(); revNodal->alloc(revNodalIndx->back(),1); + std::fill(revNodal->getPointer(),revNodal->getPointer()+revNodalIndx->back(),-1); + int *revNodalPtr=revNodal->getPointer(); + const int *connM1=ret->getNodalConnectivity()->getConstPointer(); + const int *connIndexM1=ret->getNodalConnectivityIndex()->getConstPointer(); + for(int eltId=0;eltId=0)//for polyhedrons + *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to(),-1))=eltId; + } + // + DataArrayInt *commonCells=0,*commonCellsI=0; + FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer()); + int newNbOfCellsM1=-1; + MEDCouplingAutoRefCountObjectPtr o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(), + commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1); + std::vector isImpacted(nbOfCellsM1,false); + for(const int *work=commonCellsI->begin();work!=commonCellsI->end()-1;work++) + for(int work2=work[0];work2!=work[1];work2++) + isImpacted[commonCellsPtr[work2]]=true; + const int *o2nM1Ptr=o2nM1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1); + const int *n2oM1Ptr=n2oM1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr ret2=static_cast(ret->buildPartOfMySelf(n2oM1->begin(),n2oM1->end(),true)); + ret2->copyTinyInfoFrom(this); + desc->alloc(descIndx->back(),1); + int *descPtr=desc->getPointer(); + const INTERP_KERNEL::CellModel& cmsDft=INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1); + for(int i=0;isetCoords(getCoords()); - int nbOfCellsInConstituent=(int)meshDM1Type.size(); - ret->allocateCells(nbOfCellsInConstituent); - revDescIndx->alloc(nbOfCellsInConstituent+1,1); - int *tmp3=revDescIndx->getPointer(); tmp3[0]=0; - for(int ii=0;iireserve(newNbOfCellsM1); + revDescIndx->alloc(newNbOfCellsM1+1,1); + int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0; + const int *revDesc2Ptr=revDesc2->getConstPointer(); + for(int i=0;iinsertNextCell((INTERP_KERNEL::NormalizedCellType)meshDM1Type[ii],meshDM1ConnIndex[ii+1]-meshDM1ConnIndex[ii],&meshDM1Conn[meshDM1ConnIndex[ii]]); - tmp3[ii+1]=tmp3[ii]+((int)revDescMeshConnB[ii].size()); + int oldCellIdM1=n2oM1Ptr[i]; + if(!isImpacted[oldCellIdM1]) + { + revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+1; + } + else + { + for(int j=commonCellsIPtr[0];jpushBackSilent(revDesc2Ptr[commonCellsPtr[j]]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0]; + commonCellsIPtr++; + } } - ret->finishInsertingCells(); - revDesc->alloc(tmp3[nbOfCellsInConstituent],1); - tmp3=revDesc->getPointer(); - for(std::vector< std::vector >::const_iterator iter2=revDescMeshConnB.begin();iter2!=revDescMeshConnB.end();iter2++) - tmp3=std::copy((*iter2).begin(),(*iter2).end(),tmp3); - meshDM1Type.clear(); meshDM1ConnIndex.clear(); meshDM1Conn.clear(); - descIndx->alloc(nbOfCells+1,1); - tmp3=descIndx->getPointer(); tmp3[0]=0; - for(int jj=0;jjalloc(tmp3[nbOfCells],1); - tmp3=desc->getPointer(); - for(std::vector< std::vector >::const_iterator iter3=descMeshConnB.begin();iter3!=descMeshConnB.end();iter3++) - tmp3=std::copy((*iter3).begin(),(*iter3).end(),tmp3); // - return ret; + return ret2.retn(); } struct MEDCouplingAccVisit @@ -785,20 +1026,26 @@ struct MEDCouplingAccVisit /// @endcond - /*! - * This method convert cell with ids in ['cellIdsToConvertBg','cellIdsToConvertEnd') into 'this' into dynamic types without changing geometry. - * That is to say if 'this' is a 2D, mesh after the invocation of this method it will contain only polygons. - * If 'this' is a 3D mesh after the invocation of this method it will contain only polyhedra. - * If mesh dimension is not in [2,3] an exception is thrown. - * Of course pay attention that the resulting mesh is slower than previous one. - * If in ['cellIdsToConvertBg','cellIdsToConvertEnd') there is a cell id not in [0,'this->getNumberOfCells()') an exception will be thrown. - * In this case if meshDim==2 the mesh is still valid and only cells treated before throw will be converted into polygon. - * If mesh==3, after throw the mesh is \b unconsistent ! - * This method is above all designed to test more extensively algorithms able to deal with polygons/polyhedra. - * - * \warning This method modifies can modify significantly the geometric type order in \a this. - * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. + * Converts specified cells to either polygons (if \a this is a 2D mesh) or + * polyhedrons (if \a this is a 3D mesh). The cells to convert are specified by an + * array of cell ids. Pay attention that after conversion all algorithms work slower + * with \a this mesh than before conversion.
If an exception is thrown during the + * conversion due presence of invalid ids in the array of cells to convert, as a + * result \a this mesh contains some already converted elements. In this case the 2D + * mesh remains valid but 3D mesh becomes \b inconsistent! + * \warning This method can significantly modify the order of geometric types in \a this, + * hence, to write this mesh to the MED file, its cells must be sorted using + * sortCellsInMEDFileFrmt(). + * \param [in] cellIdsToConvertBg - the array holding ids of cells to convert. + * \param [in] cellIdsToConvertEnd - a pointer to the last-plus-one-th element of \a + * cellIdsToConvertBg. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is node defined. + * \throw If dimension of \a this mesh is not either 2 or 3. + * + * \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".
+ * \ref py_mcumesh_convertToPolyTypes "Here is a Python example". */ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd) { @@ -816,7 +1063,7 @@ void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const i if(*iter>=0 && *iter
Intensive extensive